fix: make consumes_absent respect produces_kinds when flagging a real gap (2.5.68) - #748
Conversation
… gap Fixes awslabs#736. splitConsumesByPresence() computed each consumes_absent entry's expected flag purely from whether a producing stage is on the active scope's path - it never checked the current unit's kind against that producer's own produces_kinds gate. Its sibling function, resolveProduces(), already does exactly this filtering on the produces side. Result: a unit whose kind correctly excludes it from producing a given artifact (e.g. a ui-kind unit skipped for business-rules.md per functional-design.md's own produces_kinds map) was flagged expected: false (a real gap, surface it per the recovery protocol) on the next stage's directive, because the producing stage itself did run - the checker never looked one level deeper at whether this specific artifact was legitimately excluded for this unit's kind. splitConsumesByPresence now takes unitKind (mirroring resolveProduces's existing parameter) and gates producerOnPath on filterProducesByKind in addition to the existing on-path check. filterProducesByKind already returns its input unchanged when unitKind is null, so an untagged unit or a non-per-unit stage sees byte-for-byte identical behaviour. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Thank you for reporting this issue and for taking the time to isolate it with a focused implementation and regression test. The bug was valid against this branch's original base, Since then, #617, merged as This preserves I reproduced #736's exact {"stage":"nfr-requirements","unit":"web","businessRulesAbsent":[]}The merged
Rebasing this PR would make its implementation redundant and its Thank you again for identifying the original integration gap and contributing the analysis and test coverage. |
Fixes #736
Summary
consumes_absent'sexpectedflag now checks a producer's ownproduces_kindsgate before flagging an absent artifact as a real gap, so a kind-tagged unit that correctly never produces a given artifact no longer gets a false "real gap" alarm on the next stage's directive.Changes
splitConsumesByPresence(consumes, scope, codekbCtx)→splitConsumesByPresence(consumes, scope, codekbCtx, unitKind), mirroringresolveProduces's existingunitKindparameter.producerOnPath's computation now also checksfilterProducesByKind(producer.produces_kinds, [artifact], unitKind).length > 0— a producing stage being on the active scope's path is necessary but no longer sufficient; it must also actually be scoped to produce this specific artifact for this unit's kind.buildRunStageDirective(the one call site) already receivedunitKindas a parameter and already passed it toresolveProduces— it now passes it through tosplitConsumesByPresencetoo.filterProducesByKindreturns its input unchanged whenunitKindisnull, so an untagged unit or a stage with noproduces_kindsmap sees byte-for-byte identical behaviour — this is a strict narrowing of the true case, not a behaviour change for anything that isn't kind-gated.dist/viabun scripts/package.ts(not hand-edited).2.5.68(README badge + CHANGELOG).User experience
Before: a
ui-kind unit correctly never producesbusiness-rules.md(functional-design's ownproduces_kindsmap scopes it to[service, spec, library], excludingui). The next stage that consumesbusiness-rulesasrequired: true(e.g.nfr-requirements) still flags itexpected: false— "a real gap, surface it per the recovery protocol" — on its ownrun-stagedirective, becausefunctional-designitself did run. The conductor is pointed at a recovery protocol for an artifact that was never supposed to exist.After: the same
ui-kind unit'sconsumes_absententry forbusiness-rulesreportsexpected: true— its absence is by design, not a gap. Aservice-kind (or untagged) unit's identical absence at the same stage is unaffected and still correctly reportsexpected: false, sincebusiness-rulesgenuinely is in scope for that kind.Upgrade: re-copy your
dist/<harness>/shell into the project.Checklist
Test Plan
tests/unit/t279-consumes-absent-kind-gate.test.ts: (1) aui-kind unit's absentbusiness-rulesisexpected: true, not a false alarm — confirmed RED against the pre-fixdist/, then GREEN after regenerating; (2) aservice-kind unit's identical absence staysexpected: false(real gap, regression anchor); (3) an untagged unit's identical absence also staysexpected: false(unchanged, regression anchor).bun test tests/unit/t113.test.ts tests/unit/t116-directive-path-resolution.test.ts tests/unit/t207-unit-kind-schema.test.ts tests/unit/t279-consumes-absent-kind-gate.test.ts tests/unit/gen-coverage-registry.test.ts tests/unit/t68-version-changelog-sync.test.ts→ 137 pass, 0 fail.bun run check(package.ts --check+typecheck+lint) → clean (the only lint output is 3 pre-existing infos in an unrelated file,t267-usage.test.ts, unaffected by this branch).bun test tests/unit/t208-unit-kind-pruning.test.ts tests/unit/t236-ensemble-evidence-gate.test.ts→ confirmed the 21 failures in these two files reproduce identically on a pristine, unmodifiedv2checkout (unrelated environment-specific failures — missing question-flow/contribution-file fixtures, not this change) — not a regression from this branch.Acknowledgment
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the project license.