Problem
The coder archetype's "Quick Triage" section (in coder.md) mandates that the agent inspect tasks.json checkbox states and run make test at session start to determine if work is needed. However, the orchestrator's preflight check (run_preflight() in preflight.py) already performs these exact same checks — it reads checkbox states from the DB/file, checks for active findings, and runs make test — before deciding whether to launch the coder session at all. When the orchestrator decides to LAUNCH, none of its findings are passed forward to the coder, which then redundantly re-performs the same checks, wasting 2-5 tool calls and 30-90 seconds of wall-clock time per session.
Root Cause Analysis
Confidence: Confirmed
The orchestrator's preflight check runs in DispatchManager._run_preflight() (packages/agentfox/agentfox/engine/dispatch.py, lines 626-674). It calls run_preflight() (packages/agentfox/agentfox/engine/preflight.py, lines 147-184), which evaluates three gates in order:
is_task_group_done() (line 160) — checks whether all subtask checkboxes are marked complete (DB-first with file fallback)
has_active_critical_findings() (line 163) — queries DuckDB for unresolved critical/major review findings
do_tests_pass() (line 171) — runs make test with a 300-second timeout
When preflight returns PreflightVerdict.LAUNCH, the dispatcher proceeds to launch the coder session (dispatch.py, line 584-586). However, the preflight results — specifically which gate triggered the LAUNCH — are not communicated to the coder. The prepare_launch() return tuple (line 480) contains (verdict, attempt, previous_error, archetype, instances, mode) but no preflight state.
The coder then enters "Quick Triage" (coder.md, lines 18-43):
- Lines 22-25: "Inspect checkbox states in
tasks.json for your assigned task group only" — duplicates is_task_group_done() from preflight
- Lines 27-28: "If all subtasks are
[x], run make test" — duplicates do_tests_pass() from preflight
The build_task_prompt() function (session/prompt.py, lines 97-151) constructs a simple text prompt ("Implement task group N from specification X") without including any preflight state. There is no mechanism to pass the orchestrator's knowledge forward.
Related Instances
The verifier archetype also runs test suites as part of its verification, but this is not redundant because the verifier runs after the coder has made changes, verifying the post-implementation state — a fundamentally different check.
Affected Files
packages/agentfox/agentfox/engine/dispatch.py — _run_preflight() and prepare_launch() do not surface preflight gate results
packages/agentfox/agentfox/session/prompt.py — build_task_prompt() does not accept or include preflight state
packages/agentfox/agentfox/_templates/profiles/coder.md — "Quick Triage" section mandates redundant checks
Suggested Fix
Approach:
Extend the task prompt to include a brief preflight summary so the coder can skip to implementation.
-
Capture preflight gate results. When run_preflight() returns LAUNCH, record which gate triggered it and relevant state:
checkbox_state: "N/M subtasks complete" or "all complete"
findings_state: "N active critical/major findings" or "none"
tests_state: "pass" / "fail" / "not run" (tests are only run when checkboxes are all done)
-
Thread preflight state through dispatch. Add the preflight summary to prepare_launch()'s return tuple or to the SessionRecord so the session lifecycle can access it.
-
Include in task prompt. Extend build_task_prompt() to accept an optional preflight_summary string and append it:
## Preflight State (from orchestrator)
- Subtask checkboxes: 2/6 complete
- Active findings: none
- Test baseline: not run (incomplete group)
Skip Quick Triage — proceed directly to implementation.
-
Simplify Quick Triage. Update coder.md to make the Quick Triage section conditional: "If a ## Preflight State section is present in your context, skip Quick Triage entirely and proceed to Task Group Routing."
Files to modify:
packages/agentfox/agentfox/engine/preflight.py — return structured result from run_preflight() instead of bare enum
packages/agentfox/agentfox/engine/dispatch.py — thread preflight result to session lifecycle
packages/agentfox/agentfox/session/prompt.py — accept and render preflight state in build_task_prompt()
packages/agentfox/agentfox/_templates/profiles/coder.md — make Quick Triage conditional on preflight presence
Risks:
- If the preflight state is stale by the time the coder starts (e.g., another process modified the worktree), the coder might skip a needed check. Mitigate by always running tests before committing (already required by the coder profile's "Verify" section).
- The coder_fix.md (nightshift fix mode) does not use the orchestrator's preflight path — this change only affects the
af code pipeline. No impact on nightshift.
Acceptance Criteria
- AC-1: Given a coder session launched after preflight, when
build_task_prompt() is called, then the prompt includes a ## Preflight State section with checkbox completion count, findings count, and test baseline status.
- AC-2: Given a coder session with a
## Preflight State section showing incomplete subtasks and no findings, when the coder reads the prompt, then it skips the Quick Triage inspection of tasks.json and make test and proceeds directly to Task Group Routing.
- AC-3: Given a coder session without a
## Preflight State section (e.g., retry attempt or non-orchestrated run), the Quick Triage section remains active as a fallback.
- AC-4:
run_preflight() returns a structured result object (not just a bare enum) containing the gate states, without changing the existing SKIP/LAUNCH semantics.
Severity
Low — This is a performance optimization that saves 2-5 tool calls and 30-90 seconds per coder session. No correctness impact — the coder still reaches the right outcome, just more slowly.
Analysis by af-issue.
Problem
The coder archetype's "Quick Triage" section (in
coder.md) mandates that the agent inspecttasks.jsoncheckbox states and runmake testat session start to determine if work is needed. However, the orchestrator's preflight check (run_preflight()inpreflight.py) already performs these exact same checks — it reads checkbox states from the DB/file, checks for active findings, and runsmake test— before deciding whether to launch the coder session at all. When the orchestrator decides to LAUNCH, none of its findings are passed forward to the coder, which then redundantly re-performs the same checks, wasting 2-5 tool calls and 30-90 seconds of wall-clock time per session.Root Cause Analysis
Confidence: Confirmed
The orchestrator's preflight check runs in
DispatchManager._run_preflight()(packages/agentfox/agentfox/engine/dispatch.py, lines 626-674). It callsrun_preflight()(packages/agentfox/agentfox/engine/preflight.py, lines 147-184), which evaluates three gates in order:is_task_group_done()(line 160) — checks whether all subtask checkboxes are marked complete (DB-first with file fallback)has_active_critical_findings()(line 163) — queries DuckDB for unresolved critical/major review findingsdo_tests_pass()(line 171) — runsmake testwith a 300-second timeoutWhen preflight returns
PreflightVerdict.LAUNCH, the dispatcher proceeds to launch the coder session (dispatch.py, line 584-586). However, the preflight results — specifically which gate triggered the LAUNCH — are not communicated to the coder. Theprepare_launch()return tuple (line 480) contains(verdict, attempt, previous_error, archetype, instances, mode)but no preflight state.The coder then enters "Quick Triage" (coder.md, lines 18-43):
tasks.jsonfor your assigned task group only" — duplicatesis_task_group_done()from preflight[x], runmake test" — duplicatesdo_tests_pass()from preflightThe
build_task_prompt()function (session/prompt.py, lines 97-151) constructs a simple text prompt ("Implement task group N from specification X") without including any preflight state. There is no mechanism to pass the orchestrator's knowledge forward.Related Instances
The verifier archetype also runs test suites as part of its verification, but this is not redundant because the verifier runs after the coder has made changes, verifying the post-implementation state — a fundamentally different check.
Affected Files
packages/agentfox/agentfox/engine/dispatch.py—_run_preflight()andprepare_launch()do not surface preflight gate resultspackages/agentfox/agentfox/session/prompt.py—build_task_prompt()does not accept or include preflight statepackages/agentfox/agentfox/_templates/profiles/coder.md— "Quick Triage" section mandates redundant checksSuggested Fix
Approach:
Extend the task prompt to include a brief preflight summary so the coder can skip to implementation.
Capture preflight gate results. When
run_preflight()returnsLAUNCH, record which gate triggered it and relevant state:checkbox_state: "N/M subtasks complete" or "all complete"findings_state: "N active critical/major findings" or "none"tests_state: "pass" / "fail" / "not run" (tests are only run when checkboxes are all done)Thread preflight state through dispatch. Add the preflight summary to
prepare_launch()'s return tuple or to theSessionRecordso the session lifecycle can access it.Include in task prompt. Extend
build_task_prompt()to accept an optionalpreflight_summarystring and append it:Simplify Quick Triage. Update
coder.mdto make the Quick Triage section conditional: "If a## Preflight Statesection is present in your context, skip Quick Triage entirely and proceed to Task Group Routing."Files to modify:
packages/agentfox/agentfox/engine/preflight.py— return structured result fromrun_preflight()instead of bare enumpackages/agentfox/agentfox/engine/dispatch.py— thread preflight result to session lifecyclepackages/agentfox/agentfox/session/prompt.py— accept and render preflight state inbuild_task_prompt()packages/agentfox/agentfox/_templates/profiles/coder.md— make Quick Triage conditional on preflight presenceRisks:
af codepipeline. No impact on nightshift.Acceptance Criteria
build_task_prompt()is called, then the prompt includes a## Preflight Statesection with checkbox completion count, findings count, and test baseline status.## Preflight Statesection showing incomplete subtasks and no findings, when the coder reads the prompt, then it skips the Quick Triage inspection oftasks.jsonandmake testand proceeds directly to Task Group Routing.## Preflight Statesection (e.g., retry attempt or non-orchestrated run), the Quick Triage section remains active as a fallback.run_preflight()returns a structured result object (not just a bare enum) containing the gate states, without changing the existing SKIP/LAUNCH semantics.Severity
Low — This is a performance optimization that saves 2-5 tool calls and 30-90 seconds per coder session. No correctness impact — the coder still reaches the right outcome, just more slowly.
Analysis by
af-issue.