Skip to content

Guard reach: dead-output resolves consumers across workflow boundaries, so duplicate technique names mask real seams #342

Description

@m2ux

Problem

check-binding-fidelity's dead-output check resolves a consumer by bare name, without scoping it to the declaring workflow. So an output in workflow A counts as consumed when an unrelated workflow B happens to read a value of the same name — even though B has no address for A's technique and cannot bind it.

The sibling orphan-input check does not have this problem. Its own message states the scope explicitly:

own input 'selected_findings' has no producer in workflow 'workflow-design'

dead-output states no scope, and applies none:

output 'fixes_applied' is declared but nothing outside its own file consumes it
(no read, condition, binding value, remap, or same-named input)

"Outside its own file" is the whole search space. It should be "outside its own file, inside its own workflow", plus the meta library ops that are genuinely bound cross-workflow.

Evidence

Surfaced by the workflows submodule bump to f84fe02b (commit b41aaacc). The guard reported two triage entries as stale — "finding no longer occurs":

Site Output
workflow-design/techniques/apply-audit-fixes.md fixes_applied
workflow-design/techniques/yaml-authoring.md yaml_file

Neither file changed between the two corpus commits. git diff --stat 7a57d3c1..f84fe02b -- workflow-design touches only README.md and workflow.yaml. The seams are exactly as open as they were.

What changed is that #339 added workflow-authoring, whose same-named techniques read those same names:

  • workflow-authoring/techniques/workflow-definition/compile-report.md:57When `{fixes_applied}` is present, record what the remediation round changed…
  • workflow-authoring/techniques/workflow-definition/review-drafted-file.md:38diff `{yaml_file}` against the committed content at the same path…

Those reads belong to workflow-authoring. They cannot consume workflow-design's outputs: per #321, workflow-design's techniques are flat files with no group segment and therefore have no cross-workflow address — which is precisely why the additive migration had to duplicate them rather than reference them.

The two entries were pruned in b41aaacc because the guard fails until they are, and the commit message records why they are not real closures. That is the wrong outcome — the guard forced real debt out of the ledger.

Why this will grow

#321's migration is additive by design: workflow-design stays until it drains to zero, alongside workflow-authoring. The two trees currently share 16 duplicated technique basenames:

apply-audit-fixes.md          impact-analysis.md         scope-definition.md
audit-schema-validation.md    intake-classification.md   scope-verification.md
commit-verification.md        readme-authoring.md        verify-artifact-conforms.md
compile-report.md             reload-workflow.md         verify-high-findings.md
create-completion-doc.md      review-drafted-file.md     yaml-authoring.md
derive-workflows-target-path.md

Every I/O name those files share is a masking candidate, in both directions. Two have already fired. The masking is silent — it presents as a stale entry, which reads like progress.

It also outlives the migration: any two workflows that pick the same name for the same concept mask each other, and the corpus actively encourages shared vocabulary.

Requirements

R1 — Scope dead-output consumer resolution to the declaring workflow · S

A consumer in workflow B must not close a finding in workflow A. Keep the existing cross-workflow allowance for meta library ops, which are bound ad hoc by any workflow — that is what the shared-op-return-contract rationale in scripts/binding-fidelity-triage.json already describes, and it should become a scoping rule rather than a per-entry verdict.

Expect this to re-open findings, including the two b41aaacc pruned. Re-add them with their original terminal-product-unconsumed rationale.

R2 — Restore the two pruned entries · S

Falls out of R1. Listed separately so it is not lost if R1 is deferred.

R3 — Make a stale entry distinguishable from a closed one · S

The current report says only "finding no longer occurs — delete the entry". It cannot distinguish the seam was closed from the guard stopped seeing it, and it recommends deletion for both. Whatever the fix, a stale report should say enough for a reader to tell the two apart — at minimum, naming the site that now satisfies the finding, so a cross-workflow satisfier is visible on sight.

Not in scope

Renaming the duplicated techniques or accelerating workflow-design's retirement. The duplication is #321's accepted cost; the guard should be correct in its presence.

Related

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