Skip to content

Corpus binding debt: close the 125 fix-later seams #327 triaged #336

Description

@m2ux

Problem

#327 retired the binding-fidelity baseline and triaged every finding it had been silencing. The triage found and fixed three live defects, closed one whole class, and removed the false positives the guard's own blind spots were manufacturing. What remains is 125 findings classified fix-later: real seams, suppressed but counted, in scripts/binding-fidelity-triage.json.

They are suppressed honestly — each carries a written rationale, an entry that stops matching fails the guard, and there is no regenerate flag. But they are not paid down, and they are two specific shapes rather than one number:

Class Count What it is
undeclared-seed 61 No operation anywhere declares this value as an output and no workflow variable holds it, so the executing agent improvises it at the point of use.
terminal-product-unconsumed 64 A declared output with no destination: nothing binds it, no gate reads it, and it carries no #### artifact block, so the value exists only in the producing worker's report.

Why this is worth closing rather than accepting. undeclared-seed is the class #324 A1 came from. A value that is not state has to reach the worker some other way, and the way it reaches the worker is the prompt. That is the prompt-stuffing seam, measured: five baselined entries for user_request alone, and a three-hour run to find out.

Evidence

Counts are reproducible with npx tsx scripts/check-binding-fidelity.ts --emit-all against the corpus commit the triage file names.

Both classes are two ends of one seam

codebase-comprehension::survey declares four outputs that nothing consumes:

fix-later  work-package/techniques/codebase-comprehension/survey.md   architecture_overview
fix-later  work-package/techniques/codebase-comprehension/survey.md   key_abstractions
fix-later  work-package/techniques/codebase-comprehension/survey.md   design_rationale
fix-later  work-package/techniques/codebase-comprehension/survey.md   domain_glossary

The next step binds manage-artifacts::write-artifact, which declares an input nothing produces:

fix-later  work-package :: manage-artifacts::write-artifact           artifact_content
fix-later  work-package :: manage-artifacts::write-artifact           bare_filename

One missing binding, reported twice — once as a dead output, once as an orphan input. The value travels in the worker's context because the graph does not carry it. Runs work today; that is what makes it debt rather than a bug.

Distribution

Workflow undeclared-seed terminal-product-unconsumed
work-package 38 31
substrate-node-security-audit 19 10
work-packages 1 7
workflow-design 3 4
codebase-wiki 4
prism / prism-audit / prism-evaluate / prism-update 6
ponytail / remediate-vuln 2

Two workflows carry 78% of it. work-package and substrate-node-security-audit are also the two that get walked most, so the payoff is concentrated where the runs are.

Two facts that shape the work

  • None of the 61 undeclared-seed inputs is already a declared workflow variable. Every one needs a real decision — declare and seed it, or bind it from the step that produces it. There is no batch of no-ops hiding in the count.
  • 12 of the 64 terminal-product-unconsumed findings sit in techniques that already declare some #### artifact. Those are the cheap shape: the output belongs in the artifact contract next to its siblings. The other 52 need a per-case call between binding it and declaring an artifact.

Requirements

R1 — Close work-package's 69 · L

The largest and highest-traffic set. Work it as seams, not as a list: each undeclared-seed input either becomes declared state (a workflow.yaml variable, seeded) or gains a binding from the step that already computes it, and the matching dead output on the other end of the seam clears with it. Expect the count to fall faster than 1:1 — the surveywrite-artifact example closes six findings with one binding.

Prune the triage entries as they clear; the stale-entry check will name them.

R2 — Close substrate-node-security-audit's 29 · M

Same shape. This workflow's inputs (crate_map, file_inventory, source_files, scan_scope, search_scope, workspace_root) look like one reconnaissance product fanned out to many consumers, so a single declared envelope may close most of the set.

R3 — Declare the 12 artifact-shaped outputs · S

The outputs in techniques that already declare an #### artifact. Add the block; the guard exempts artifact-carrying outputs because the server consumes them when it synthesizes the activity contract. Cheapest measurable progress in the issue.

R4 — Sweep the remaining 15 across the small workflows · S

work-packages, workflow-design, codebase-wiki, the prism family, ponytail, remediate-vuln. Small enough to take in one pass once R1 and R2 have established the pattern.

R5 — Decide what terminal-product-unconsumed means for a library op · S

Some of the 64 are the terminal product of a workflow's last activity, where there is genuinely nothing downstream — prism's run_status is one. If a declared output with no consumer is legitimate for a terminal step, that deserves its own rationale and a harmless verdict rather than sitting in the debt column. Decide the rule once and re-verdict against it, rather than deciding it 64 times.

Not in scope

Suggested sequencing

R3 (12 artifact declarations, immediate and mechanical) → R5 (decide the terminal-output rule before spending effort on findings that may not be debt) → R2 (substrate, likely one envelope) → R1 (work-package, the long pole) → R4 (the tail).

Adjacent finding: discuss is a checkpoint wearing a technique's clothes

Not part of the 125 and not a completion criterion for this issue — recorded here because it sits inside R1's territory and whoever works requirements-elicitation will hit it.

work-package/techniques/requirements-elicitation/discuss.md:

## Capability

Prompt the user for the stakeholder discussion transcript before agent-led elicitation begins,
offering a skip path with a noted limitation.

## Protocol

### 1. Prompt Transcript

- Prompt user for the {stakeholder_transcript} before elicitation
- Offer skip option with note about limitation if no {stakeholder_transcript} is provided
- If the user skips stakeholder discussion entirely, note the limitation and proceed with
  agent-led elicitation

That is session interaction inside a technique — Keep Session Interaction in Activities: "Techniques are session-blind… They do not know about user sessions or how to interact with humans."

And the work is already done by structure: the step immediately after it in 03-requirements-elicitation.yaml is the stakeholder-transcript checkpoint, which does the asking and offers the skip path, writing has_stakeholder_input from its option effects.

How it surfaced. #327 removed has_stakeholder_input from this technique's Outputs, because the checkpoint is its single writer and the technique was claiming a value it does not produce. That closed the finding. It did not address why the technique declared it: the op duplicates the checkpoint. The binding guard cannot see this class at all — a technique that prompts is structurally indistinguishable from one that computes.

Likely shape of the fix: the checkpoint keeps the interaction and the variables; discuss either goes away or shrinks to whatever non-interactive product it actually contributes. That is a design decision about the activity, which is why #327 left it rather than folding it into a debt paydown.


Related

🤖 Generated with Claude Code

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