Skip to content

Asymmetry: sub_dag_task_ids dropped from PreparedBriefing but kept on runtime Briefing #10

Description

@fgmacedo

Context

Recent commit 19e6e9a ("director: drop sub_dag_task_ids from PreparedBriefing, resolve from DAG") removed sub_dag_task_ids from the PreparedBriefing struct, the inline-by-Planner shape used when the Planner provides a prepared_briefing on a phase, skipping the Briefer agent. The motivation was supporting resume after partial completion: listing already-done tasks in a static slice was rejected by the validator, so the synthetic briefing now resolves its sub-DAG dynamically from live DAG state (every task in the phase still pending or needs_fix).

A later commit 9594dd9 ("docs: drop sub_dag_task_ids from plan schema and prune stale doc references") cleaned up the trailing schema reference in plan.schema.json that was still requiring the field on PreparedBriefing, plus stale doc references to deleted spec files.

Current state

sub_dag_task_ids is still alive in the runtime Briefing struct (the Briefer-emitted, per-iteration shape). Specifically, it is still present in:

  • internal/supervision/types.go:117, Briefing.SubDAGTaskIDs []string
  • internal/supervision/schemas/briefing.schema.json:8, required field
  • internal/supervision/schemas/mcp/briefing_emit.schema.json:13, required on briefing_emit input
  • internal/supervision/dag/handler.go:778, handler rejects empty sub_dag_task_ids on briefing_emit
  • internal/supervision/dag/handler.go:683, get_briefing returns it
  • internal/supervision/prompts/brief.md:25, Briefer prompt instructs to emit it
  • internal/supervision/prompts/review.md lines 8, 17, Reviewer prompt reads it via get_briefing and iterates
  • Various tests, plus docs references in docs/guides/director.md and docs/guides/director.pt-BR.md

So the two paths into the loop now disagree on how the sub-DAG is determined:

  • Synthetic path (PreparedBriefing from Planner): sub-DAG resolved dynamically from live DAG state.
  • Briefer path (Briefing emitted via briefing_emit): sub-DAG declared as an explicit static slice, validated by the handler.

This asymmetry has at least three observable consequences worth flagging:

  1. Two mental models for the same concept (what tasks does this iteration cover?).
  2. The resume problem that motivated 19e6e9a could in principle hit the Briefer path too: if a Briefer emits a sub_dag_task_ids slice that includes a task that just transitioned to done, the handler rejects the emit. Today the Briefer is prompted to only include pending/needs_fix, so it does not surface in practice, but it is a possible foot-gun.
  3. The field flows into the Reviewer prompt and shapes how it iterates acceptance. Removing it would require restructuring how the Reviewer learns which tasks are in scope for the current iteration.

Open question

Should the asymmetry be resolved by also dropping sub_dag_task_ids from the runtime Briefing, mirroring what 19e6e9a did for PreparedBriefing, OR is the asymmetry intentional (Briefer-emitted shape is the agent's declaration; synthetic-path resolution is a special case)?

This is a discussion issue, not a bug. No definitive resolution proposed.

Migration surface if we go the "remove" route

A future PR going down the "remove from runtime too" path would need to touch:

  • internal/supervision/dag/handler.go, the briefing_emit validation (line 778 empty-check and the surrounding sub-DAG checks around lines 780-792), the get_briefing response shape (line 683), and the approval-iteration code that consumes bs.briefing.SubDAGTaskIDs (lines 716-717, 1230-1231).
  • internal/supervision/schemas/briefing.schema.json and internal/supervision/schemas/mcp/briefing_emit.schema.json, drop the required field and its description.
  • internal/supervision/types.go, drop Briefing.SubDAGTaskIDs.
  • internal/supervision/prompts/brief.md, drop the instruction to emit it (line 25 and surrounding template).
  • internal/supervision/prompts/review.md, restructure how the Reviewer learns which tasks are in scope for the current iteration (lines 8 and 17 currently rely on the field).
  • Tests under internal/supervision/ and internal/supervision/dag/ that fixture or assert on sub_dag_task_ids.
  • Docs: docs/guides/director.md and docs/guides/director.pt-BR.md (the troubleshooting bullet at line 153 in each references the empty sub_dag_task_ids error).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions