@@ -64,6 +64,15 @@ Plus a `BudgetVerdict` from the agent's per-month USD cost budget
6464(` ProviderBudgetTracker ` ). ` BudgetPressure ` comes out as ` NoPressure ` ,
6565` NearExhaustion ` , or ` Exhausted ` .
6666
67+ The ` SpawnContext ` also carries ** per-agent Gitea identity** . When the
68+ orchestrator's ` OutputPoster ` has loaded an entry for ` (project, agent) `
69+ from ` agent_tokens.json ` , ` build_spawn_context_for_agent ` injects
70+ ` GITEA_TOKEN ` into ` env_overrides ` . This overrides the shared root token
71+ from ` ~/.profile ` , so ` gtr ` / ` curl ` calls inside the agent's own task
72+ shell authenticate as the agent's own Gitea user — not ` root ` . The
73+ ` OutputPoster ` wrapper comment + any direct ` gtr comment ` the agent
74+ makes both show ` author = <agent-name> ` in Gitea.
75+
6776## Stage 2: RoutingDecisionEngine picks the model
6877
6978` crates/terraphim_orchestrator/src/control_plane/routing.rs ` —
@@ -306,16 +315,57 @@ Resolves the per-project `GiteaTracker`, looks up the per-agent Gitea token
306315(` agent_tokens.json ` ) so the comment lands under the agent's own login, and
307316POSTs to ` /api/v1/repos/{owner}/{repo}/issues/{issue_number}/comments ` .
308317
309- ### Known bug recently fixed (adf-fleet #44 )
318+ ### Known bug recently fixed (adf-fleet #44 , PR # 738 )
310319
311- Before commit ` 7cf60d2c ` (PR # 738 ) , ` RepoComment::issue_number ` was extracted
312- only from ` issue_url ` . For comments on pull requests Gitea returns
320+ Before commit ` 7cf60d2c ` , ` RepoComment::issue_number ` was extracted only
321+ from ` issue_url ` . For comments on pull requests Gitea returns
313322` pull_request_url ` instead, so every PR comment arrived with
314323` issue_number = 0 ` and OutputPoster tried to post to ` /issues/0/comments ` —
315324500 from Gitea. The fix reads ` pull_request_url ` as a fallback. PRs share
316325the issue numeric namespace so the same trailing-segment extraction works
317326for both URLs.
318327
328+ ### Per-agent identity end-to-end (PR #741 )
329+
330+ ` OutputPoster::has_own_token ` controls the wrapper comment's author.
331+ ` OutputPoster::agent_token(project, name) ` exposes the raw token string
332+ so ` build_spawn_context_for_agent ` can inject ` GITEA_TOKEN ` into the
333+ spawned child's env. Together these close the attribution loop:
334+
335+ | Path | Token used | Gitea author |
336+ | ---| ---| ---|
337+ | OutputPoster wrapper: "Agent X completed" | per-agent | X |
338+ | Agent's own ` gtr comment ` in task shell | per-agent (via env override) | X |
339+ | Agent lookup misses ` agent_tokens.json ` | project root token | root |
340+
341+ ` agent_tokens.json ` maps every agent name listed in ` conf.d/*.toml ` to a
342+ Gitea personal access token. If the map is empty or the path is not set
343+ on ` [projects.gitea] ` , every agent on that project falls back to ` root ` .
344+
345+ ### Meta-coordinator as work dispatcher
346+
347+ On both ` digital-twins ` and ` terraphim-ai ` the meta-coordinator's task
348+ envelope now follows the canonical scope-gate + dispatch pattern from
349+ ` scripts/adf-setup/agents/meta-coordinator.toml ` :
350+
351+ 1 . ` gtr ready ` → highest-PageRank unblocked issue
352+ 2 . Haiku scope-clarity check via ` claude -p --model haiku --allowedTools "" `
353+ (pure text, no tool surface — prompt-injection safe)
354+ 3 . If unclear → ` gtr comment ` with a "needs more detail" note, skip if
355+ already posted in the last 24 h (idempotency)
356+ 4 . If clear → Haiku role classifier picks one of
357+ implementation-swarm, quality-coordinator, security-sentinel,
358+ compliance-watchdog, spec-validator, test-guardian,
359+ documentation-generator
360+ 5 . ` gtr comment "@adf:<role> please pick up issue #N" ` on the ready
361+ issue → the mention parser dispatches the named role at the next
362+ poll tick
363+
364+ Terraphim's previous fleet-health-report pattern (writing to
365+ ` /opt/ai-dark-factory/reports/ ` and posting to issue ` #107 ` ) has been
366+ replaced. Fleet-health reporting is now the job of ` fleet-meta `
367+ (cross-project) and the journal + Quickwit indices.
368+
319369## Example: trace from the journal
320370
321371Security-sentinel got a model at 17:33:08 CEST on 2026-04-21:
0 commit comments