Summary
A full workflow-design update pass and a bare two-agent "apply the anti-pattern catalogue and the design principles to this diff" sweep were run against the same branch, in the same session, hours apart. The bare sweep found more real defects for roughly a third of the tokens. This issue proposes cutting workflow-design down to what earned its keep.
This is not a claim that structure is worthless — the workflow's audit stages found three genuine High defects, and two of its planning activities each produced one load-bearing insight. It is a claim that the current shape spends most of its budget on delivery overhead and on artifacts nobody reads.
The measurement
Both runs targeted workflow/work-package-review-mode-friction-271 (PR #274). Token figures are harness-reported subagent totals.
|
workflow-design pass 1 |
Two bare sweeps |
| Worker dispatches |
12 |
2 |
| Subagent tokens |
~1,430,000 |
~410,000 |
| Wall clock |
~2h |
~40m |
| High findings |
3 |
8 |
| Cost per High |
~477k |
~51k |
Per-activity breakdown of the workflow run: discover-session 58k · initialize-session 43k · resolve-target 33k · dispatch-client-workflow 42k · intake-and-context 152k · requirements-refinement 160k · impact-analysis 108k · scope-and-draft 177k · quality-review 192k · validate-and-commit 92k + 142k · post-update-review 231k.
All three of the workflow's High findings came from its two audit stages. The four planning activities consumed ~600k and produced no High findings — though see "what we would lose" below, because two of them produced insights that prevented a wrong fix.
Artifacts: 17 files, 106KB, six with no reader
Produced by the run, by size:
03-assumptions-log.md 13.7K · 06-scope-manifest.md 9.5K · 01-deferred-items.md 8.5K · 10-post-update-review.md 8.3K · README.md 7.5K · 06-draft-attestation.md 7.4K · 10-principle-findings.md 7.3K · 03-design-specification.md 7.1K · 05-impact-analysis.md 7.0K · 01-structural-inventory.md 5.2K · 10-anti-pattern-findings.md 5.0K · 08-conformance-findings.md 4.2K · 08-verified-findings.md 3.5K · 01-format-conventions.md 3.4K · 08-expressiveness-findings.md 3.0K · 06-file-review-note.md 3.0K · 06-drafting-plan.md 2.4K
The six in bold — 25KB, about a quarter of the total — were never read by the user, never cited in any decision, and never consumed by a downstream step. Each still cost a technique load, a persist step, verify-artifact-conforms checking, and a Progress table row.
Artifacts that demonstrably earned their place: the deferred register (became #319), the findings satellites (their content drove the fix cycle), the scope manifest and assumptions log (both fed real Gate 2 decisions — the manifest caught a four-files-not-three discrepancy), and the planning README (the one thing a human navigates).
Three causes, largest first
1. Per-dispatch re-delivery dominates the budget
dispatch-activity's workers-need-full-delivery requires each worker to be a fresh context with no prior deliveries — correct for isolation, but it means all 12 workers re-pull the operations bundle, their activity, their step techniques and their resources before doing any work. The meta orchestrator bundle alone serialises to ~50KB. Twelve fresh contexts × (bundle + activity + techniques + resources) accounts for most of the 1M-token gap against two dispatches.
This is architectural rather than incidental: activity count is the primary cost driver, largely independent of how much work each activity does.
2. Splitting the audit by lens structurally prevents the best findings
quality-review runs six audit techniques, each scoped to one dimension, each persisting its own satellite. post-update-review repeats five of them. The bare sweep instead gave one agent the entire diff.
That difference is not cosmetic — it decided what was findable. Two of the most serious defects live between files and could not be seen by any single-lens pass:
- A review type could contradict its own summary:
work-package/workflow.yaml:335 adds review_type as a checkpoint-set variable while update-pr/post-review-comment.md:34 still asserted the cap was inherited "with no separate variable" — so a supplied approve skipped the derivation and would post an approving review over a Request-Changes body.
13-submit-for-review.yaml re-rendered the review summary after the user approved it and before posting it "verbatim", while the committed artifact kept the pre-refresh links — spanning a step order and two technique rules.
Both were missed by the in-workflow audits and found by the sweep.
3. The machinery carries its own bug population
Seven of the ten items in this run's deferred register are defects in workflow-design's own definitions: D-1 (mode-gating disagreement across three surfaces), D-2 (seed inventory gap), D-4 and D-7 (artifact_content bound to names with no producer, so the string resolves as a literal and the step would persist the variable's name), D-8 (two UNRESOLVED technique inputs), D-9 (nine restated defaults), D-10 (a canon rule that, read literally, makes verify-artifact-conforms fail by construction).
D-4 and D-7 are the sharpest: every worker that hit them reported spending effort working around them. The workflow's own persist machinery is a tax on the workflow's own runs.
Compounding this, four attestation gates auto-resolved without reaching the user (#317), including one that waved through three removals under an outcome clause reading "every flagged removal is one the user consciously approved". Where the ceremony exists to record human consent, it was recording consent nobody gave.
What the sweep did differently, beyond being smaller
These are replicable and belong in whatever replaces the audit stages:
- Attribution against base was mandatory. Every candidate was checked with
git show origin/workflows:<path>; inherited content was reported separately. This eliminated the re-litigation of pre-existing noise that consumed effort in earlier passes.
- Known items were excluded up front. The prompt listed already-tracked findings, so zero effort went to rediscovery.
- Negatives had to be evidenced. "Entries applied that pass, where a plausible exposure existed" — which is exactly what the in-workflow rule-hygiene passes lacked. They reported 0 findings twice while never reading a technique
## Rules section, the surface where two real defects were later found by hand.
- One context held the whole surface, enabling the cross-file findings above.
Planning outcome — this supersedes the original proposal below
Full record: .engineering/artifacts/planning/2026-07-28-workflow-design-slim-down — six corpus maps, three competing architectures, three judge verdicts, the implementation plan, two adversarial passes.
The proposal as originally written below was tested and lost. Three target architectures were designed independently and scored by three judges, one lens each. The framing that took this issue literally — the scope/draft/audit/land rename and 17→5 — scored lowest on all three lenses:
| Proposal |
Canon |
Migration |
Efficacy |
Total |
| value-preserving |
8 |
7 |
8 |
23 |
| delivery-first |
6 |
5 |
7 |
18 |
| minimal-cut (this issue, literally) |
4 |
4 |
5 |
13 |
The settled shape
|
Original proposal |
Settled |
| Activities |
9 → 4, renamed |
9 → 4, ids preserved (intake-and-context, scope-and-draft, quality-review, validate-and-commit), sparse prefixes 01/06/08/09 kept |
| Techniques |
not addressed |
37 → 23 (19 retired, 5 added) |
| Artifacts |
17 → 5 |
17 → 6 |
| Delivery |
not addressed |
one whole-surface audit-canon sweep replacing six per-lens passes |
| Migration |
in-place rewrite + delete |
additive, on a new workflow id |
Renaming the activities was the single worst idea in the original proposal. Prefix and id renumbering buys cosmetics and pays for it in the @-column of 32 live planning folders, and — see below — in stranded sessions.
Migration is additive, not in place
The original plan rewrote workflow-design's activity files and deleted five. That bricks 21 of 32 running sessions: readActivityRaw matches the filename-derived id with no fallback (src/loaders/workflow-loader.ts:570, error at :615), and validateActivityTransition returns null on an empty valid set (src/utils/validation.ts:45), so next_activity succeeds silently — the failure only surfaces when get_activity throws. 19 of the 21 sit at retrospective.
Instead: author the slim design as a new workflow, workflow-authoring v1.0.0, and leave workflow-design untouched. Sessions drain naturally. Registration needs nothing but the directory — discovery is a readdir + isDirectory() scan, and workflow.yaml never enumerates its activities, which is what lets the migration land one activity at a time (S1–S8, each leaving a validating workflow terminated at __terminal__).
Retirement is gated on a drain-to-zero trigger: a committed census script that recurses triggeredWorkflows[i].state, an append-only drain log, and a ≥90-day abandonment policy — because nobody is obliged to finish the 19 parked sessions, so zero must be reachable, not merely measurable.
This dissolves the Critical plus four other findings. Its honest cost: ~18 technique files must be duplicated, because workflow-design's techniques are flat files with no group segment and therefore have no cross-workflow address. The 154 KB canon does not need duplicating — cross-workflow resource refs work, provided the link is authored in the relative .md form the loader projects.
Blocking defect, to be fixed in the authored YAML
transitionTo is "Recorded and returned, not engine-applied" (src/schema/activity.schema.ts:50). So selecting remediate does not move the session: the worker continues through the rest of the activity, presents the commit gate anyway, writes COMPLETE.md on a non-terminal pass, and removes the worktree the remediation round then needs to author into. Five further defects are listed in the planning record; all are fixable during authoring.
Original proposal — superseded, retained for the record
Activities: 9 → 4
| New |
Absorbs |
Emits |
scope |
intake-and-context, requirements-refinement, pattern-analysis, impact-analysis |
change surface, binding constraints, open judgements |
draft |
scope-and-draft |
the edits |
audit |
quality-review, post-update-review |
one findings register; bounded fix cycle; blocking gate on Critical |
land |
validate-and-commit, retrospective |
Gate 2, commit, push, PR, close-out |
Artifacts: 17 → 5
Keep: planning README (Progress + links), scope record (surface + constraints + open judgements, replacing design-specification + assumptions-log + impact-analysis + scope-manifest), findings register (one file replacing six satellites), deferred register, COMPLETE.md.
Drop: format-conventions, structural-inventory, drafting-plan, file-review-note, draft-attestation, verified-findings.
The test an artifact must pass
A named reader and a decision it feeds. If neither exists, it does not get written. Attestation records specifically are redundant: the session trace already holds every checkpoint response, and get_trace resolves it at close-out.
Audit stage design
One whole-surface sweep, not per-lens passes. Carry over the four properties above: mandatory base attribution, known-items exclusion, evidenced negatives, single context over the whole diff. A bounded fix cycle and a blocking gate on Critical — blocking, because the current gate sat in activity-level decisions evaluated at exit, so a Critical finding was announced and attested anyway.
What we would lose, and how to protect it
Honest accounting — two planning activities did earn their keep, once each:
requirements-refinement established that closing the orphan input was a re-target, not a rename: .engineering/ is a nested checkout on branch engineering while the parent sits on main, so binding to a parent-repo path yields exactly the value the technique forbids hardcoding. Without that, the fix would have been wrong.
impact-analysis found the change surface was four files not three, and that the obvious fix name would shadow declared I/O and introduce fresh drift.
Both are constraint discovery, and both are cheap to ask for directly. The merged scope activity should demand them explicitly — "what does this change actually target, what constrains the fix, what must a human decide" — rather than relying on four activities to surface them incidentally.
Gate 2 stays. It caught the four-files discrepancy and disposed two open judgements. The judgement trail stays too, inside the scope record rather than as a separate log.
Suggested validation
Before committing to the cut, re-run the same branch through the proposed 4-activity shape and compare against both baselines in the table above. The target is ≤500k tokens — roughly the sweep cost plus drafting — with no loss in High findings. If the slimmed shape cannot match 8 Highs, the gap identifies what genuinely needed the ceremony.
A finding that generalises beyond this issue
anti-patterns.md has 13 ## sections, and AP-126/127/128/129 sit inside ## Authoring Guidance (MR) rather than in an anti-pattern family section. Any catalogue walk that enumerates ## *Anti-Patterns families therefore drops them silently — including AP-128 and AP-129, the two entries the slim-down most depends on. That is a reliability problem for every catalogue sweep, including the bare sweep that motivated this issue.
Related
Summary
A full
workflow-designupdate pass and a bare two-agent "apply the anti-pattern catalogue and the design principles to this diff" sweep were run against the same branch, in the same session, hours apart. The bare sweep found more real defects for roughly a third of the tokens. This issue proposes cuttingworkflow-designdown to what earned its keep.This is not a claim that structure is worthless — the workflow's audit stages found three genuine High defects, and two of its planning activities each produced one load-bearing insight. It is a claim that the current shape spends most of its budget on delivery overhead and on artifacts nobody reads.
The measurement
Both runs targeted
workflow/work-package-review-mode-friction-271(PR #274). Token figures are harness-reported subagent totals.workflow-designpass 1Per-activity breakdown of the workflow run: discover-session 58k · initialize-session 43k · resolve-target 33k · dispatch-client-workflow 42k · intake-and-context 152k · requirements-refinement 160k · impact-analysis 108k · scope-and-draft 177k · quality-review 192k · validate-and-commit 92k + 142k · post-update-review 231k.
All three of the workflow's High findings came from its two audit stages. The four planning activities consumed ~600k and produced no High findings — though see "what we would lose" below, because two of them produced insights that prevented a wrong fix.
Artifacts: 17 files, 106KB, six with no reader
Produced by the run, by size:
03-assumptions-log.md13.7K ·06-scope-manifest.md9.5K ·01-deferred-items.md8.5K ·10-post-update-review.md8.3K ·README.md7.5K ·06-draft-attestation.md7.4K ·10-principle-findings.md7.3K ·03-design-specification.md7.1K ·05-impact-analysis.md7.0K ·01-structural-inventory.md5.2K ·10-anti-pattern-findings.md5.0K ·08-conformance-findings.md4.2K ·08-verified-findings.md3.5K ·01-format-conventions.md3.4K ·08-expressiveness-findings.md3.0K ·06-file-review-note.md3.0K ·06-drafting-plan.md2.4KThe six in bold — 25KB, about a quarter of the total — were never read by the user, never cited in any decision, and never consumed by a downstream step. Each still cost a technique load, a persist step,
verify-artifact-conformschecking, and a Progress table row.Artifacts that demonstrably earned their place: the deferred register (became #319), the findings satellites (their content drove the fix cycle), the scope manifest and assumptions log (both fed real Gate 2 decisions — the manifest caught a four-files-not-three discrepancy), and the planning README (the one thing a human navigates).
Three causes, largest first
1. Per-dispatch re-delivery dominates the budget
dispatch-activity'sworkers-need-full-deliveryrequires each worker to be a fresh context with no prior deliveries — correct for isolation, but it means all 12 workers re-pull the operations bundle, their activity, their step techniques and their resources before doing any work. Themetaorchestrator bundle alone serialises to ~50KB. Twelve fresh contexts × (bundle + activity + techniques + resources) accounts for most of the 1M-token gap against two dispatches.This is architectural rather than incidental: activity count is the primary cost driver, largely independent of how much work each activity does.
2. Splitting the audit by lens structurally prevents the best findings
quality-reviewruns six audit techniques, each scoped to one dimension, each persisting its own satellite.post-update-reviewrepeats five of them. The bare sweep instead gave one agent the entire diff.That difference is not cosmetic — it decided what was findable. Two of the most serious defects live between files and could not be seen by any single-lens pass:
work-package/workflow.yaml:335addsreview_typeas a checkpoint-set variable whileupdate-pr/post-review-comment.md:34still asserted the cap was inherited "with no separate variable" — so a suppliedapproveskipped the derivation and would post an approving review over a Request-Changes body.13-submit-for-review.yamlre-rendered the review summary after the user approved it and before posting it "verbatim", while the committed artifact kept the pre-refresh links — spanning a step order and two technique rules.Both were missed by the in-workflow audits and found by the sweep.
3. The machinery carries its own bug population
Seven of the ten items in this run's deferred register are defects in
workflow-design's own definitions: D-1 (mode-gating disagreement across three surfaces), D-2 (seed inventory gap), D-4 and D-7 (artifact_contentbound to names with no producer, so the string resolves as a literal and the step would persist the variable's name), D-8 (twoUNRESOLVEDtechnique inputs), D-9 (nine restated defaults), D-10 (a canon rule that, read literally, makesverify-artifact-conformsfail by construction).D-4 and D-7 are the sharpest: every worker that hit them reported spending effort working around them. The workflow's own persist machinery is a tax on the workflow's own runs.
Compounding this, four attestation gates auto-resolved without reaching the user (#317), including one that waved through three removals under an outcome clause reading "every flagged removal is one the user consciously approved". Where the ceremony exists to record human consent, it was recording consent nobody gave.
What the sweep did differently, beyond being smaller
These are replicable and belong in whatever replaces the audit stages:
git show origin/workflows:<path>; inherited content was reported separately. This eliminated the re-litigation of pre-existing noise that consumed effort in earlier passes.## Rulessection, the surface where two real defects were later found by hand.Planning outcome — this supersedes the original proposal below
Full record:
.engineering/artifacts/planning/2026-07-28-workflow-design-slim-down— six corpus maps, three competing architectures, three judge verdicts, the implementation plan, two adversarial passes.The proposal as originally written below was tested and lost. Three target architectures were designed independently and scored by three judges, one lens each. The framing that took this issue literally — the
scope/draft/audit/landrename and 17→5 — scored lowest on all three lenses:The settled shape
intake-and-context,scope-and-draft,quality-review,validate-and-commit), sparse prefixes01/06/08/09keptaudit-canonsweep replacing six per-lens passesRenaming the activities was the single worst idea in the original proposal. Prefix and id renumbering buys cosmetics and pays for it in the
@-column of 32 live planning folders, and — see below — in stranded sessions.Migration is additive, not in place
The original plan rewrote
workflow-design's activity files and deleted five. That bricks 21 of 32 running sessions:readActivityRawmatches the filename-derived id with no fallback (src/loaders/workflow-loader.ts:570, error at:615), andvalidateActivityTransitionreturnsnullon an empty valid set (src/utils/validation.ts:45), sonext_activitysucceeds silently — the failure only surfaces whenget_activitythrows. 19 of the 21 sit atretrospective.Instead: author the slim design as a new workflow,
workflow-authoringv1.0.0, and leaveworkflow-designuntouched. Sessions drain naturally. Registration needs nothing but the directory — discovery is areaddir+isDirectory()scan, andworkflow.yamlnever enumerates its activities, which is what lets the migration land one activity at a time (S1–S8, each leaving a validating workflow terminated at__terminal__).Retirement is gated on a drain-to-zero trigger: a committed census script that recurses
triggeredWorkflows[i].state, an append-only drain log, and a ≥90-day abandonment policy — because nobody is obliged to finish the 19 parked sessions, so zero must be reachable, not merely measurable.This dissolves the Critical plus four other findings. Its honest cost: ~18 technique files must be duplicated, because
workflow-design's techniques are flat files with no group segment and therefore have no cross-workflow address. The 154 KB canon does not need duplicating — cross-workflow resource refs work, provided the link is authored in the relative.mdform the loader projects.Blocking defect, to be fixed in the authored YAML
transitionTois "Recorded and returned, not engine-applied" (src/schema/activity.schema.ts:50). So selectingremediatedoes not move the session: the worker continues through the rest of the activity, presents the commit gate anyway, writesCOMPLETE.mdon a non-terminal pass, and removes the worktree the remediation round then needs to author into. Five further defects are listed in the planning record; all are fixable during authoring.Original proposal — superseded, retained for the record
Activities: 9 → 4
scopedraftauditlandArtifacts: 17 → 5
Keep: planning README (Progress + links), scope record (surface + constraints + open judgements, replacing design-specification + assumptions-log + impact-analysis + scope-manifest), findings register (one file replacing six satellites), deferred register, COMPLETE.md.
Drop:
format-conventions,structural-inventory,drafting-plan,file-review-note,draft-attestation,verified-findings.The test an artifact must pass
A named reader and a decision it feeds. If neither exists, it does not get written. Attestation records specifically are redundant: the session trace already holds every checkpoint response, and
get_traceresolves it at close-out.Audit stage design
One whole-surface sweep, not per-lens passes. Carry over the four properties above: mandatory base attribution, known-items exclusion, evidenced negatives, single context over the whole diff. A bounded fix cycle and a blocking gate on Critical — blocking, because the current gate sat in activity-level
decisionsevaluated at exit, so a Critical finding was announced and attested anyway.What we would lose, and how to protect it
Honest accounting — two planning activities did earn their keep, once each:
requirements-refinementestablished that closing the orphan input was a re-target, not a rename:.engineering/is a nested checkout on branchengineeringwhile the parent sits onmain, so binding to a parent-repo path yields exactly the value the technique forbids hardcoding. Without that, the fix would have been wrong.impact-analysisfound the change surface was four files not three, and that the obvious fix name would shadow declared I/O and introduce fresh drift.Both are constraint discovery, and both are cheap to ask for directly. The merged
scopeactivity should demand them explicitly — "what does this change actually target, what constrains the fix, what must a human decide" — rather than relying on four activities to surface them incidentally.Gate 2 stays. It caught the four-files discrepancy and disposed two open judgements. The judgement trail stays too, inside the scope record rather than as a separate log.
Suggested validation
Before committing to the cut, re-run the same branch through the proposed 4-activity shape and compare against both baselines in the table above. The target is ≤500k tokens — roughly the sweep cost plus drafting — with no loss in High findings. If the slimmed shape cannot match 8 Highs, the gap identifies what genuinely needed the ceremony.
A finding that generalises beyond this issue
anti-patterns.mdhas 13##sections, and AP-126/127/128/129 sit inside## Authoring Guidance (MR)rather than in an anti-pattern family section. Any catalogue walk that enumerates## *Anti-Patternsfamilies therefore drops them silently — including AP-128 and AP-129, the two entries the slim-down most depends on. That is a reliability problem for every catalogue sweep, including the bare sweep that motivated this issue.Related
workflow-designself-defects and are the maintenance cost this issue argues is too high for the value returned.