harness-everything 0.34.0 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +25 -0
- package/ci/fixtures/doc-obligations/derive/acceptance-only/base/docs/prd/graph.md +22 -0
- package/ci/fixtures/doc-obligations/derive/acceptance-only/candidate/docs/prd/graph.md +22 -0
- package/ci/fixtures/doc-obligations/derive/alias-only/base/docs/prd/graph.md +24 -0
- package/ci/fixtures/doc-obligations/derive/alias-only/candidate/docs/prd/graph.md +24 -0
- package/ci/fixtures/doc-obligations/derive/assertion-no-revision/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/assertion-no-revision/base/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/assertion-no-revision/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/assertion-no-revision/candidate/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/assertion-no-revision-attested/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/assertion-no-revision-attested/base/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/assertion-no-revision-attested/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/assertion-no-revision-attested/candidate/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/assertion-no-revision-attested/inventory.json +7 -0
- package/ci/fixtures/doc-obligations/derive/attribution-impossible/base/ci/mechanism-open.test.js +3 -0
- package/ci/fixtures/doc-obligations/derive/attribution-impossible/candidate/ci/mechanism-open.test.js.fixture +2 -0
- package/ci/fixtures/doc-obligations/derive/clause-context-typo/base/docs/prd/graph.md +24 -0
- package/ci/fixtures/doc-obligations/derive/clause-context-typo/candidate/docs/prd/graph.md +24 -0
- package/ci/fixtures/doc-obligations/derive/code-only/base/src/lint.js +1 -0
- package/ci/fixtures/doc-obligations/derive/code-only/candidate/src/lint.js +1 -0
- package/ci/fixtures/doc-obligations/derive/comment-only-test/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/comment-only-test/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/computed-member-assert/base/ci/mechanism-c1.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/computed-member-assert/candidate/ci/mechanism-c1.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/computed-member-variable/base/ci/mechanism-c1.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/computed-member-variable/candidate/ci/mechanism-c1.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/config.json +11 -0
- package/ci/fixtures/doc-obligations/derive/decision-fence-backtick/base/docs/adr/GRPH-010.md +20 -0
- package/ci/fixtures/doc-obligations/derive/decision-fence-backtick/candidate/docs/adr/GRPH-010.md +20 -0
- package/ci/fixtures/doc-obligations/derive/decision-fence-tilde/base/docs/adr/GRPH-010.md +20 -0
- package/ci/fixtures/doc-obligations/derive/decision-fence-tilde/candidate/docs/adr/GRPH-010.md +20 -0
- package/ci/fixtures/doc-obligations/derive/deep-strict-equal/base/ci/mechanism-s1.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/deep-strict-equal/candidate/ci/mechanism-s1.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/deleted-adr/base/docs/adr/GRPH-008.md +14 -0
- package/ci/fixtures/doc-obligations/derive/deleted-prd/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/deleted-prd/base/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/deleted-prd/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/derived-rename/base/docs/index.md +3 -0
- package/ci/fixtures/doc-obligations/derive/derived-rename/base/src/model/a.js +1 -0
- package/ci/fixtures/doc-obligations/derive/derived-rename/candidate/docs/index.md +3 -0
- package/ci/fixtures/doc-obligations/derive/derived-rename/candidate/src/model/b.js +1 -0
- package/ci/fixtures/doc-obligations/derive/derived-rename/config.json +7 -0
- package/ci/fixtures/doc-obligations/derive/derived-two-outputs/base/docs/index.md +3 -0
- package/ci/fixtures/doc-obligations/derive/derived-two-outputs/base/docs/model-summary.md +3 -0
- package/ci/fixtures/doc-obligations/derive/derived-two-outputs/base/src/model.js +1 -0
- package/ci/fixtures/doc-obligations/derive/derived-two-outputs/candidate/docs/index.md +3 -0
- package/ci/fixtures/doc-obligations/derive/derived-two-outputs/candidate/docs/model-summary.md +3 -0
- package/ci/fixtures/doc-obligations/derive/derived-two-outputs/candidate/src/model.js +1 -0
- package/ci/fixtures/doc-obligations/derive/derived-two-outputs/config.json +10 -0
- package/ci/fixtures/doc-obligations/derive/distinct-logical-prds/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/distinct-logical-prds/base/docs/prd/graph-one/r001.md +19 -0
- package/ci/fixtures/doc-obligations/derive/distinct-logical-prds/base/docs/prd/graph-two/r001.md +19 -0
- package/ci/fixtures/doc-obligations/derive/distinct-logical-prds/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/distinct-logical-prds/candidate/docs/prd/graph-one/r001.md +19 -0
- package/ci/fixtures/doc-obligations/derive/distinct-logical-prds/candidate/docs/prd/graph-two/r001.md +19 -0
- package/ci/fixtures/doc-obligations/derive/docs-only/base/docs/reference/guide.md +3 -0
- package/ci/fixtures/doc-obligations/derive/docs-only/candidate/docs/reference/guide.md +3 -0
- package/ci/fixtures/doc-obligations/derive/dup-req-id/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/dup-req-id/base/docs/prd/graph-a.md +20 -0
- package/ci/fixtures/doc-obligations/derive/dup-req-id/base/docs/prd/graph-b.md +20 -0
- package/ci/fixtures/doc-obligations/derive/dup-req-id/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/dup-req-id/candidate/docs/prd/graph-a.md +20 -0
- package/ci/fixtures/doc-obligations/derive/dup-req-id/candidate/docs/prd/graph-b.md +20 -0
- package/ci/fixtures/doc-obligations/derive/expect-computed-literal/base/ci/mechanism-e.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/expect-computed-literal/candidate/ci/mechanism-e.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/expect-computed-matcher/base/ci/mechanism-e.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/expect-computed-matcher/candidate/ci/mechanism-e.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/expect-not-to-equal/base/ci/mechanism-s1.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/expect-not-to-equal/candidate/ci/mechanism-s1.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/formatting-only-test/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/formatting-only-test/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/helper-delegated-test/base/docs/prd/graph.md +18 -0
- package/ci/fixtures/doc-obligations/derive/helper-delegated-test/candidate/ci/mechanism-helper.test.js +1 -0
- package/ci/fixtures/doc-obligations/derive/helper-delegated-test/candidate/docs/prd/graph.md +18 -0
- package/ci/fixtures/doc-obligations/derive/historical-only-req/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/historical-only-req/base/docs/prd/graph/r001.md +25 -0
- package/ci/fixtures/doc-obligations/derive/historical-only-req/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/historical-only-req/candidate/docs/prd/graph/r001.md +25 -0
- package/ci/fixtures/doc-obligations/derive/historical-only-req/candidate/docs/prd/graph/r002.md +23 -0
- package/ci/fixtures/doc-obligations/derive/in-place-current/base/ci/mechanism-inplace.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/in-place-current/base/docs/prd/graph/r001.md +20 -0
- package/ci/fixtures/doc-obligations/derive/in-place-current/base/docs/prd/graph/r002.md +26 -0
- package/ci/fixtures/doc-obligations/derive/in-place-current/candidate/ci/mechanism-inplace.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/in-place-current/candidate/docs/prd/graph/r001.md +20 -0
- package/ci/fixtures/doc-obligations/derive/in-place-current/candidate/docs/prd/graph/r002.md +28 -0
- package/ci/fixtures/doc-obligations/derive/in-place-historical/base/ci/mechanism-inplace.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/in-place-historical/base/docs/prd/graph/r001.md +20 -0
- package/ci/fixtures/doc-obligations/derive/in-place-historical/base/docs/prd/graph/r002.md +26 -0
- package/ci/fixtures/doc-obligations/derive/in-place-historical/candidate/ci/mechanism-inplace.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/in-place-historical/candidate/docs/prd/graph/r001.md +22 -0
- package/ci/fixtures/doc-obligations/derive/in-place-historical/candidate/docs/prd/graph/r002.md +26 -0
- package/ci/fixtures/doc-obligations/derive/invalid-clause/base/docs/prd/graph.md +24 -0
- package/ci/fixtures/doc-obligations/derive/invalid-clause/candidate/docs/prd/graph.md +24 -0
- package/ci/fixtures/doc-obligations/derive/legacy-untagged-fallback/base/ci/mechanism-legacy.test.js +6 -0
- package/ci/fixtures/doc-obligations/derive/legacy-untagged-fallback/candidate/ci/mechanism-legacy.test.js +6 -0
- package/ci/fixtures/doc-obligations/derive/literal-whitespace-assert/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/literal-whitespace-assert/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/malformed-citation-attribution/base/ci/mechanism-bad.test.js +6 -0
- package/ci/fixtures/doc-obligations/derive/malformed-citation-attribution/candidate/ci/mechanism-bad.test.js.fixture +6 -0
- package/ci/fixtures/doc-obligations/derive/malformed-prd/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/malformed-prd/base/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/malformed-prd/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/malformed-prd/candidate/docs/prd/graph.md +11 -0
- package/ci/fixtures/doc-obligations/derive/missing-approval/base/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/missing-approval/candidate/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/mixed-attribution/base/ci/mechanism-mixed.test.js +6 -0
- package/ci/fixtures/doc-obligations/derive/mixed-attribution/base/docs/prd/graph.md +24 -0
- package/ci/fixtures/doc-obligations/derive/mixed-attribution/candidate/ci/mechanism-mixed.test.js.fixture +5 -0
- package/ci/fixtures/doc-obligations/derive/mixed-attribution/candidate/docs/prd/graph.md +24 -0
- package/ci/fixtures/doc-obligations/derive/mixed-docs-code/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/mixed-docs-code/base/docs/reference/guide.md +3 -0
- package/ci/fixtures/doc-obligations/derive/mixed-docs-code/base/src/lint.js +1 -0
- package/ci/fixtures/doc-obligations/derive/mixed-docs-code/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/mixed-docs-code/candidate/docs/reference/guide.md +3 -0
- package/ci/fixtures/doc-obligations/derive/mixed-docs-code/candidate/src/lint.js +1 -0
- package/ci/fixtures/doc-obligations/derive/multiline-comment-only/base/ci/mechanism-multi.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/multiline-comment-only/candidate/ci/mechanism-multi.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/multiline-expect/base/ci/mechanism-multi.test.js +6 -0
- package/ci/fixtures/doc-obligations/derive/multiline-expect/candidate/ci/mechanism-multi.test.js +6 -0
- package/ci/fixtures/doc-obligations/derive/multiline-formatting-only/base/ci/mechanism-multi.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/multiline-formatting-only/candidate/ci/mechanism-multi.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/multiline-numeric-prd/base/ci/mechanism-multi.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/multiline-numeric-prd/base/docs/prd/graph.md +18 -0
- package/ci/fixtures/doc-obligations/derive/multiline-numeric-prd/candidate/ci/mechanism-multi.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/multiline-numeric-prd/candidate/docs/prd/graph.md +18 -0
- package/ci/fixtures/doc-obligations/derive/multiline-strictequal/base/ci/mechanism-multi.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/multiline-strictequal/candidate/ci/mechanism-multi.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/new-prd/candidate/docs/prd/graph-new.md +20 -0
- package/ci/fixtures/doc-obligations/derive/new-reference/candidate/docs/reference/new-note.md +3 -0
- package/ci/fixtures/doc-obligations/derive/new-req-test/candidate/ci/mechanism-new.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/orphan-req-test/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/orphan-req-test/base/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/orphan-req-test/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/orphan-req-test/candidate/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/partial-revision/base/ci/mechanism-partial.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/partial-revision/base/docs/prd/graph/r001.md +24 -0
- package/ci/fixtures/doc-obligations/derive/partial-revision/candidate/ci/mechanism-partial.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/partial-revision/candidate/docs/prd/graph/r001.md +24 -0
- package/ci/fixtures/doc-obligations/derive/partial-revision/candidate/docs/prd/graph/r002.md +26 -0
- package/ci/fixtures/doc-obligations/derive/regex-literal-whitespace/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/regex-literal-whitespace/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/rename/base/docs/reference/old-guide.md +3 -0
- package/ci/fixtures/doc-obligations/derive/rename/candidate/docs/reference/guide.md +3 -0
- package/ci/fixtures/doc-obligations/derive/replacement-target/base/docs/prd/graph.md +24 -0
- package/ci/fixtures/doc-obligations/derive/replacement-target/candidate/docs/prd/graph.md +24 -0
- package/ci/fixtures/doc-obligations/derive/req-context-typo/base/docs/prd/graph.md +26 -0
- package/ci/fixtures/doc-obligations/derive/req-context-typo/candidate/docs/prd/graph.md +26 -0
- package/ci/fixtures/doc-obligations/derive/req-revision/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/req-revision/base/docs/prd/graph/r001.md +20 -0
- package/ci/fixtures/doc-obligations/derive/req-revision/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/req-revision/candidate/docs/prd/graph/r001.md +20 -0
- package/ci/fixtures/doc-obligations/derive/req-revision/candidate/docs/prd/graph/r002.md +28 -0
- package/ci/fixtures/doc-obligations/derive/req-revision-in-place/base/docs/prd/graph/r001.md +20 -0
- package/ci/fixtures/doc-obligations/derive/req-revision-in-place/candidate/docs/prd/graph/r001.md +22 -0
- package/ci/fixtures/doc-obligations/derive/retained-revision-chain/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/retained-revision-chain/base/docs/prd/graph/r001.md +20 -0
- package/ci/fixtures/doc-obligations/derive/retained-revision-chain/base/docs/prd/graph/r002.md +26 -0
- package/ci/fixtures/doc-obligations/derive/retained-revision-chain/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/retained-revision-chain/candidate/docs/prd/graph/r001.md +20 -0
- package/ci/fixtures/doc-obligations/derive/retained-revision-chain/candidate/docs/prd/graph/r002.md +26 -0
- package/ci/fixtures/doc-obligations/derive/string-literal-tag/base/ci/mechanism-str.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/string-literal-tag/candidate/ci/mechanism-str.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/tag-inside-test-call/base/ci/mechanism-inside.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/tag-inside-test-call/candidate/ci/mechanism-inside.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/tagged-test/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/tagged-test/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/tagged-test-prd/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/tagged-test-prd/base/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/tagged-test-prd/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/tagged-test-prd/candidate/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/template-literal-tag/base/ci/mechanism-tpl.test.js +4 -0
- package/ci/fixtures/doc-obligations/derive/template-literal-tag/base/docs/prd/graph.md +18 -0
- package/ci/fixtures/doc-obligations/derive/template-literal-tag/candidate/ci/mechanism-tpl.test.js +4 -0
- package/ci/fixtures/doc-obligations/derive/template-literal-tag/candidate/docs/prd/graph.md +18 -0
- package/ci/fixtures/doc-obligations/derive/template-literal-whitespace/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/template-literal-whitespace/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/title-only-rename/base/ci/mechanism-title.test.js +3 -0
- package/ci/fixtures/doc-obligations/derive/title-only-rename/candidate/ci/mechanism-title.test.js +3 -0
- package/ci/fixtures/doc-obligations/derive/title-only-unrelated-computed/base/ci/mechanism-u.test.js +4 -0
- package/ci/fixtures/doc-obligations/derive/title-only-unrelated-computed/candidate/ci/mechanism-u.test.js +4 -0
- package/ci/fixtures/doc-obligations/derive/top-level-no-file-tag/base/ci/mechanism-top.test.js +4 -0
- package/ci/fixtures/doc-obligations/derive/top-level-no-file-tag/candidate/ci/mechanism-top.test.js +4 -0
- package/ci/fixtures/doc-obligations/derive/trailing-comment-test/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/trailing-comment-test/base/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/trailing-comment-test/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/trailing-comment-test/candidate/docs/prd/graph.md +20 -0
- package/ci/fixtures/doc-obligations/derive/two-tests-one-file/base/ci/mechanism-two.test.js +6 -0
- package/ci/fixtures/doc-obligations/derive/two-tests-one-file/base/docs/prd/graph.md +24 -0
- package/ci/fixtures/doc-obligations/derive/two-tests-one-file/candidate/ci/mechanism-two.test.js +6 -0
- package/ci/fixtures/doc-obligations/derive/two-tests-one-file/candidate/docs/prd/graph.md +24 -0
- package/ci/fixtures/doc-obligations/derive/typo-context/base/docs/adr/GRPH-007.md +14 -0
- package/ci/fixtures/doc-obligations/derive/typo-context/candidate/docs/adr/GRPH-007.md +14 -0
- package/ci/fixtures/doc-obligations/derive/typo-decision/base/docs/adr/GRPH-007.md +14 -0
- package/ci/fixtures/doc-obligations/derive/typo-decision/candidate/docs/adr/GRPH-007.md +14 -0
- package/ci/fixtures/doc-obligations/derive/unbalanced-statement/base/ci/mechanism-multi.test.js +5 -0
- package/ci/fixtures/doc-obligations/derive/unbalanced-statement/candidate/ci/mechanism-multi.test.js.fixture +4 -0
- package/ci/fixtures/doc-obligations/derive/unknown-adr/base/docs/adr/GRPH-009.md +14 -0
- package/ci/fixtures/doc-obligations/derive/unknown-adr/candidate/docs/adr/GRPH-009.md +12 -0
- package/ci/fixtures/doc-obligations/derive/unsupported-assertion-syntax/base/ci/mechanism-s1.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/unsupported-assertion-syntax/candidate/ci/mechanism-s1.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/whitespace-only-test/base/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/derive/whitespace-only-test/candidate/ci/mechanism-lint.test.js +2 -0
- package/ci/fixtures/doc-obligations/evidence/base/docs/adr/GRPH-007.md +15 -0
- package/ci/fixtures/doc-obligations/evidence/base/docs/prd/PRD-GRPH-001.md +25 -0
- package/ci/fixtures/doc-obligations/evidence/candidate/docs/adr/GRPH-007.md +15 -0
- package/ci/fixtures/doc-obligations/evidence/candidate/docs/prd/PRD-GRPH-001.md +25 -0
- package/ci/mechanism-325-3a-cross.test.js +795 -0
- package/ci/mechanism-325-3a-doc-evidence.test.js +1172 -0
- package/ci/mechanism-325-3a-doc-obligations.test.js +742 -0
- package/ci/mechanism-pr334-haiku.test.js +298 -0
- package/ci/mechanism-pr334-luna.test.js +192 -0
- package/ci/mechanism-pr334-opencode.test.js +313 -0
- package/ci/mechanism-pr334-r2-boundary.test.js +239 -0
- package/ci/mechanism-pr334-r2-resolution.test.js +243 -0
- package/ci/mechanism-pr334-r2-scope.test.js +127 -0
- package/ci/mechanism-pr334-r3-boundary.test.js +356 -0
- package/ci/mechanism-pr334-r3-citations.test.js +205 -0
- package/ci/mechanism-pr334-r3-headings.test.js +268 -0
- package/docs/document-lifecycle.md +57 -1
- package/harness-everything/SKILL.md +1 -1
- package/harness-everything/scripts/doc-evidence.js +471 -0
- package/harness-everything/scripts/doc-lifecycle.js +1 -1
- package/harness-everything/scripts/doc-obligations.js +1571 -0
- package/opencode-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
- package/plugins/harness-everything/plugin.json +1 -1
- package/plugins/harness-everything/skills/harness-everything/SKILL.md +1 -1
- package/plugins/harness-everything/skills/harness-everything/scripts/doc-evidence.js +471 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/doc-lifecycle.js +1 -1
- package/plugins/harness-everything/skills/harness-everything/scripts/doc-obligations.js +1571 -0
- package/sbom.cdx.json +7 -7
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// PR #334 round 3 — heading boundary regressions in section extraction.
|
|
4
|
+
//
|
|
5
|
+
// extractSection in doc-obligations.js recognized only column-zero ATX headings. A
|
|
6
|
+
// CommonMark-valid Decision headings indented 1..3 spaces were invisible, so a real
|
|
7
|
+
// Decision edit reported quality-review and conflict-check N/A. Related boundary
|
|
8
|
+
// controls cover Setext Decision headings and tab-indented fence lookalikes.
|
|
9
|
+
//
|
|
10
|
+
// Authoritative rule: https://spec.commonmark.org/0.31.2/#atx-headings
|
|
11
|
+
// * 0-3 ASCII spaces of indentation, then 1-6 "#", then a space/tab or end of line;
|
|
12
|
+
// * 4 spaces or a leading tab is code indentation, not a heading;
|
|
13
|
+
// * a closing sequence must be preceded by a space/tab.
|
|
14
|
+
//
|
|
15
|
+
// Scope is bounded to Decision section boundaries. This is not a CommonMark parser.
|
|
16
|
+
// Fence and code boundaries are exercised as regression controls.
|
|
17
|
+
//
|
|
18
|
+
// Every case runs the full deriveDocFacts -> deriveDocObligations pipeline. Expectations
|
|
19
|
+
// come from the spec and the D6.5 normative-change rule, not from the implementation.
|
|
20
|
+
|
|
21
|
+
const assert = require('assert');
|
|
22
|
+
const fs = require('fs');
|
|
23
|
+
const path = require('path');
|
|
24
|
+
const helper = require('./test-helper');
|
|
25
|
+
|
|
26
|
+
const modulePath = path.join(__dirname, '..', 'harness-everything', 'scripts', 'doc-obligations.js');
|
|
27
|
+
const fixtureDir = path.join(__dirname, 'fixtures', 'doc-obligations', 'derive');
|
|
28
|
+
const CONFIG = JSON.parse(fs.readFileSync(path.join(fixtureDir, 'config.json'), 'utf8'));
|
|
29
|
+
const ADR = 'docs/adr/GRPH-007.md';
|
|
30
|
+
|
|
31
|
+
let deriveDocFacts;
|
|
32
|
+
let deriveDocObligations;
|
|
33
|
+
try {
|
|
34
|
+
({ deriveDocFacts, deriveDocObligations } = require(modulePath));
|
|
35
|
+
} catch (error) {
|
|
36
|
+
helper.check('pr334-r3-headings. derive module is available', false, error.message);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
console.log('\n[pr334-r3-headings] ATX heading indentation in Decision section extraction...');
|
|
40
|
+
|
|
41
|
+
function readFixture(caseName, side, file = 'GRPH-007.md') {
|
|
42
|
+
return fs.readFileSync(path.join(fixtureDir, caseName, side, 'docs', 'adr', file), 'utf8');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Existing typo-decision fixture: one Decision body word changes "lint" -> "lnt".
|
|
46
|
+
const TYPO_BASE = readFixture('typo-decision', 'base');
|
|
47
|
+
const TYPO_CANDIDATE = readFixture('typo-decision', 'candidate');
|
|
48
|
+
|
|
49
|
+
function adr(body) {
|
|
50
|
+
return ['---', 'id: GRPH-007', 'role: adr', 'status: accepted', '---', '# GRPH-007 Lint first', '', body, ''].join('\n');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function replaceOnce(text, from, to) {
|
|
54
|
+
assert.strictEqual(text.split(from).length, 2, `fixture text contains exactly one "${from}"`);
|
|
55
|
+
return text.replace(from, to);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function indentDecision(text, prefix) {
|
|
59
|
+
return replaceOnce(text, '## Decision', `${prefix}## Decision`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function applicability(base, candidate, file = ADR) {
|
|
63
|
+
const result = deriveDocFacts({
|
|
64
|
+
base: { files: { [file]: base } },
|
|
65
|
+
candidate: { files: { [file]: candidate } },
|
|
66
|
+
config: CONFIG
|
|
67
|
+
});
|
|
68
|
+
const obligations = deriveDocObligations(result.facts);
|
|
69
|
+
return new Map(obligations.map(item => [item.capability, item.applicability]));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// The normative capabilities must agree with each other; doc-lint and link-check always apply to a governed edit.
|
|
73
|
+
function assertDecisionEdit(name, base, candidate, want, file = ADR) {
|
|
74
|
+
const map = applicability(base, candidate, file);
|
|
75
|
+
assert.strictEqual(map.get('doc-lint'), 'applicable', `${name}: doc-lint`);
|
|
76
|
+
assert.strictEqual(map.get('link-check'), 'applicable', `${name}: link-check`);
|
|
77
|
+
assert.strictEqual(map.get('quality-review'), want, `${name}: quality-review`);
|
|
78
|
+
assert.strictEqual(map.get('conflict-check'), want, `${name}: conflict-check`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function checkCase(name, run) {
|
|
82
|
+
try {
|
|
83
|
+
run();
|
|
84
|
+
helper.check(name, true);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
helper.check(name, false, error && error.message ? error.message : String(error));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Matrix 1: indentation of the real Decision heading. 0-3 spaces are headings; 4 spaces and a leading tab are code.
|
|
91
|
+
for (const [label, prefix] of [['0 spaces', ''], ['1 space', ' '], ['2 spaces', ' '], ['3 spaces', ' ']]) {
|
|
92
|
+
checkCase(`pr334-r3 indent matrix: Decision heading with ${label} is a heading; Decision edit is normative`, () => {
|
|
93
|
+
assertDecisionEdit(label, indentDecision(TYPO_BASE, prefix), indentDecision(TYPO_CANDIDATE, prefix), 'applicable');
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
for (const [label, prefix] of [['4 spaces', ' '], ['a leading tab', '\t']]) {
|
|
98
|
+
checkCase(`pr334-r3 indent matrix: Decision heading with ${label} is code, not a heading; the edit is non-normative`, () => {
|
|
99
|
+
assertDecisionEdit(label, indentDecision(TYPO_BASE, prefix), indentDecision(TYPO_CANDIDATE, prefix), 'N/A');
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Matrix 2: fences. Existing fixtures keep their behavior; an indented fenced fake heading stays ignored.
|
|
104
|
+
for (const caseName of ['decision-fence-backtick', 'decision-fence-tilde']) {
|
|
105
|
+
checkCase(`pr334-r3 fence control: ${caseName} fixture still treats the real Decision as normative`, () => {
|
|
106
|
+
assertDecisionEdit(caseName, readFixture(caseName, 'base', 'GRPH-010.md'), readFixture(caseName, 'candidate', 'GRPH-010.md'), 'applicable', 'docs/adr/GRPH-010.md');
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
checkCase('pr334-r3 fence: a 3-space indented fenced "## Decision" is ignored; the real Decision edit stays applicable (not unknown)', () => {
|
|
111
|
+
const base = adr('## Context\n\nWe need lint.\n\n ```md\n ## Decision\n ```\n\n## Decision\n\nRun lint first.');
|
|
112
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
113
|
+
assertDecisionEdit('indented fence', base, candidate, 'applicable');
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
checkCase('pr334-r3 fence: an indented tilde fence does not hide the following 3-space Decision heading', () => {
|
|
117
|
+
const base = adr('## Context\n\nWe need lint.\n\n ~~~md\n# Example\n ~~~\n\n ## Decision\n\nRun lint first.');
|
|
118
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
119
|
+
assertDecisionEdit('indented tilde fence', base, candidate, 'applicable');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
checkCase('pr334-r3 fence: a tab-indented fence-looking line does not hide a following Decision heading', () => {
|
|
123
|
+
const base = adr('## Context\n\nWe need lint.\n\n\t```md\n ## Decision\n\nRun lint first.');
|
|
124
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
125
|
+
assertDecisionEdit('tab-indented opener', base, candidate, 'applicable');
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
checkCase('pr334-r3 fence: a tab-indented closer inside a real fence does not expose a fake Decision heading', () => {
|
|
129
|
+
const base = adr('## Context\n\nWe need lint.\n\n```md\n \t```\n## Decision\n\nFake text.\n```\n\n## Decision\n\nRun lint first.');
|
|
130
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
131
|
+
assertDecisionEdit('tab-indented closer', base, candidate, 'applicable');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
checkCase('pr334-r3 fence: a backtick in a backtick-fence info string invalidates the opener, so Decision is visible', () => {
|
|
135
|
+
const base = adr(['## Context', '', '```js `', '', '## Decision', '', 'Run lint first.'].join('\n'));
|
|
136
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
137
|
+
assertDecisionEdit('malformed backtick info', base, candidate, 'applicable');
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
checkCase('pr334-r3 fence: a tilde-fence info string may contain a backtick and still hides its fake Decision', () => {
|
|
141
|
+
const base = adr(['## Context', '', '~~~js `', '## Decision', 'Fake text.', '~~~', '', '## Decision', '', 'Run lint first.'].join('\n'));
|
|
142
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
143
|
+
assertDecisionEdit('tilde info backtick', base, candidate, 'applicable');
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
checkCase('pr334-r3 setext: a suspected standalone Setext Decision yields unknown, never N/A', () => {
|
|
147
|
+
const base = adr('## Context\n\nWe need lint.\n\nDecision\n--------\n\nRun lint first.');
|
|
148
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
149
|
+
assertDecisionEdit('Setext Decision', base, candidate, 'unknown');
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
checkCase('pr334-r3 setext: a multiline Setext paragraph ending in "Decision" stays unknown rather than a false Decision section', () => {
|
|
153
|
+
const base = adr('## Context\n\nWe need lint.\n\nContext prose\nDecision\n--------\n\nRun lint first.');
|
|
154
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
155
|
+
assertDecisionEdit('multiline Setext title', base, candidate, 'unknown');
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
checkCase('pr334-r3 setext: a Setext-looking Decision inside a fence is ignored', () => {
|
|
159
|
+
const base = adr('## Context\n\nWe need lint.\n\n```md\nDecision\n--------\nFake text.\n```\n\n## Decision\n\nRun lint first.');
|
|
160
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
161
|
+
assertDecisionEdit('Setext in fence', base, candidate, 'applicable');
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
checkCase('pr334-r3 setext: an unsupported Setext boundary inside Decision yields unknown instead of guessing its paragraph scope', () => {
|
|
165
|
+
const base = adr('## Decision\n\nRun lint first.\n\nNext\n---\n\nLater.');
|
|
166
|
+
const candidate = base.replace('Next\n---', 'Next steps\n---');
|
|
167
|
+
assertDecisionEdit('unsupported Setext boundary', base, candidate, 'unknown');
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
checkCase('pr334-r3 thematic break: a rule after the ATX Decision remains inside the section', () => {
|
|
171
|
+
const base = adr('## Decision\n\n---\n\nRun lint first.');
|
|
172
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
173
|
+
assertDecisionEdit('thematic break after ATX', base, candidate, 'applicable');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
checkCase('pr334-r3 thematic break: a rule after a fenced block does not turn its closing fence into a Setext heading', () => {
|
|
177
|
+
const base = adr('## Decision\n\n```js\nexample();\n```\n---\nUse A.');
|
|
178
|
+
const candidate = base.replace('Use A.', 'Use B.');
|
|
179
|
+
assertDecisionEdit('thematic break after fence', base, candidate, 'applicable');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
checkCase('pr334-r3 setext: four-space-indented Setext-looking text is code, not a Decision heading', () => {
|
|
183
|
+
const base = adr('## Context\n\nWe need lint.\n\n Decision\n --------\n\nRun lint first.');
|
|
184
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
185
|
+
assertDecisionEdit('Setext in code', base, candidate, 'N/A');
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Matrix 3: section termination and inclusion.
|
|
189
|
+
checkCase('pr334-r3 termination: a 3-space subsection (### Consequences) is included in the Decision section', () => {
|
|
190
|
+
const base = adr(' ## Decision\n\nRun lint first.\n\n ### Consequences\n\nLint is cheap.');
|
|
191
|
+
const candidate = base.replace('Lint is cheap.', 'Lnt is cheap.');
|
|
192
|
+
assertDecisionEdit('subsection', base, candidate, 'applicable');
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
checkCase('pr334-r3 termination: a 3-space same-level heading (## Next) ends the Decision section; an edit there is non-normative', () => {
|
|
196
|
+
const base = adr(' ## Decision\n\nRun lint first.\n\n ## Next\n\nLint later.');
|
|
197
|
+
const candidate = base.replace('Lint later.', 'Lnt later.');
|
|
198
|
+
assertDecisionEdit('same-level terminator', base, candidate, 'N/A');
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
checkCase('pr334-r3 termination: a 1-space higher-level heading (# Appendix) ends the Decision section; an edit there is non-normative', () => {
|
|
202
|
+
const base = adr(' ## Decision\n\nRun lint first.\n\n # Appendix\n\nLint notes.');
|
|
203
|
+
const candidate = base.replace('Lint notes.', 'Lnt notes.');
|
|
204
|
+
assertDecisionEdit('higher-level terminator', base, candidate, 'N/A');
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
checkCase('pr334-r3 termination: an empty "##" heading line ends the Decision section; an edit after it is non-normative', () => {
|
|
208
|
+
const base = adr(' ## Decision\n\nRun lint first.\n\n##\n\nLint notes.');
|
|
209
|
+
const candidate = base.replace('Lint notes.', 'Lnt notes.');
|
|
210
|
+
assertDecisionEdit('empty terminator', base, candidate, 'N/A');
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
checkCase('pr334-r3 termination: a 4-space indented "## Example" is code and does not end the Decision section', () => {
|
|
214
|
+
const base = adr(' ## Decision\n\nRun lint first.\n\n ## Example\n\nLint sample.');
|
|
215
|
+
const candidate = base.replace('Lint sample.', 'Lnt sample.');
|
|
216
|
+
assertDecisionEdit('code-indented non-terminator', base, candidate, 'applicable');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// Matrix 4: duplicate Decision headings are ambiguous, whatever the indentation.
|
|
220
|
+
checkCase('pr334-r3 duplicate: a column-0 Decision plus a 2-space Decision is unknown, never N/A or applicable', () => {
|
|
221
|
+
const base = adr('## Decision\n\nRun lint first.\n\n ## Decision\n\nOther.');
|
|
222
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
223
|
+
assertDecisionEdit('duplicate', base, candidate, 'unknown');
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// Matrix 5: closing sequences and separators, per the ATX rule. Only space/tab separators and preceding-space closings count.
|
|
227
|
+
checkCase('pr334-r3 closing: a 2-space "## Decision ##" closing sequence is the Decision heading', () => {
|
|
228
|
+
const base = adr(' ## Decision ##\n\nRun lint first.');
|
|
229
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
230
|
+
assertDecisionEdit('closing', base, candidate, 'applicable');
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
checkCase('pr334-r3 closing: "## Decision#" has no preceding space, so the title is "Decision#" and Decision is absent', () => {
|
|
234
|
+
const base = adr('## Decision#\n\nRun lint first.');
|
|
235
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
236
|
+
assertDecisionEdit('glued hash', base, candidate, 'N/A');
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
checkCase('pr334-r3 separator: a tab after the hashes ("##\\tDecision") is a valid separator', () => {
|
|
240
|
+
const base = adr('##\tDecision\n\nRun lint first.');
|
|
241
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
242
|
+
assertDecisionEdit('tab separator', base, candidate, 'applicable');
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
checkCase('pr334-r3 separator: a no-break space after the hashes is not a CommonMark separator, so it is not a heading', () => {
|
|
246
|
+
const base = adr('## Decision\n\nRun lint first.');
|
|
247
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
248
|
+
assertDecisionEdit('nbsp separator', base, candidate, 'N/A');
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
checkCase('pr334-r3 separator: "##Decision" with no separator is not a heading (control)', () => {
|
|
252
|
+
const base = adr('##Decision\n\nRun lint first.');
|
|
253
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
254
|
+
assertDecisionEdit('no separator', base, candidate, 'N/A');
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
checkCase('pr334-r3 level: seven hashes is not an ATX heading (control)', () => {
|
|
258
|
+
const base = adr('####### Decision\n\nRun lint first.');
|
|
259
|
+
const candidate = base.replace('Run lint first.', 'Run lnt first.');
|
|
260
|
+
assertDecisionEdit('seven hashes', base, candidate, 'N/A');
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Positive control: the column-0 typo-decision fixture is unchanged by this fix.
|
|
264
|
+
checkCase('pr334-r3 control: the existing column-0 typo-decision fixture stays normative', () => {
|
|
265
|
+
assertDecisionEdit('typo-decision', TYPO_BASE, TYPO_CANDIDATE, 'applicable');
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
helper.finish();
|
|
@@ -11,7 +11,8 @@ Documentation is a **consumer** of the #320 workflow/obligation abstractions. No
|
|
|
11
11
|
| 0 — contract + RED fixtures | This file; fixtures under `ci/fixtures/doc-lifecycle/` |
|
|
12
12
|
| 1a — `project-docs.json` loader | `multi-agent-workspace/scripts/project-docs-resolver.js` |
|
|
13
13
|
| 2 — roles, IDs, aliases, legacy, supersession, index, D6.9 PRD revisions | `harness-everything/scripts/doc-lifecycle.js` |
|
|
14
|
-
|
|
|
14
|
+
| 3a — `doc-change` / `requirement-sync` pure derivation and evidence producer | `harness-everything/scripts/doc-obligations.js` (facts and obligations), `harness-everything/scripts/doc-evidence.js` (`checkDocObligations`). Pilot-local: not wired into workflow disposition yet. H3 and H4 have deterministic tests; H1 and H2 are deferred to 3c. Known limits: the attested-envelope fields are caller-asserted (`configDigest` is checked for presence only, not against the parsed config); `candidateDigest` covers only `docs/prd/`, so custom PRD roots and task-scope binding are not yet verified; deleted and renamed paths fail closed (#335) |
|
|
15
|
+
| 1b, 3b–3c (provider suggestions, reconciliation, H1–H2 evaluation) | Not started: blocked by #320 family metadata, D1 obligation schema and D3 evidence states. Known gap: deleted and old rename paths cannot get candidate-bound evidence, so their MUSTs fail closed |
|
|
15
16
|
| 4 — derived-view generators, `describes:` drift | Not started |
|
|
16
17
|
|
|
17
18
|
## Configuration (D5)
|
|
@@ -195,6 +196,61 @@ Anchors for cross-file diagnostics: `supersede-*`, `unresolved-ref`, `ambiguous-
|
|
|
195
196
|
|
|
196
197
|
`invalid-prd-id`, `invalid-revision`, `duplicate-revision`, `missing-parent`, `multiple-baselines`, `revision-cycle`, `revision-fork`, `stale-draft-base`, `invalid-transition`, `approval-missing`, `approval-content-mismatch`, `revision-digest-mismatch`, `immutable-revision-modified`, `immutable-revision-deleted`, `req-dropped`, `incomplete-snapshot`, `invalid-req-clause`, `replacement-alias-overlap`, `replacement-cycle`. `not-observed` is an evidence disposition, not a diagnostic and not a pass.
|
|
197
198
|
|
|
199
|
+
## D6.5 — `doc-change` applicability by diff facts (Decided; revised 2026-10-16)
|
|
200
|
+
|
|
201
|
+
Not a single class enum. The diff yields **facts**; required checks are the **union** of what each fact triggers. If a fact cannot be determined, assume it is present (`unknown` never downgrades to trivial).
|
|
202
|
+
|
|
203
|
+
| Fact (from diff) | Triggers |
|
|
204
|
+
| --- | --- |
|
|
205
|
+
| Any governed file touched | Lint (role/status/ID/alias); in-repo link check |
|
|
206
|
+
| Text/format only (no fact below) | Nothing more |
|
|
207
|
+
| New governed file | Update-over-create check; outline confirmation (MUST for PRD/ADR, SHOULD otherwise) |
|
|
208
|
+
| Declared derived source affected | Regenerate + regenerate-equals |
|
|
209
|
+
| **Normative field**: frontmatter `status`/`supersedes`, PRD REQ block/acceptance, ADR *Decision* section | Quality review (MUST); D6.4 conflict check |
|
|
210
|
+
| Governed reference/guide content | Prose > 50% reminder (SHOULD) |
|
|
211
|
+
| Code or REQ-citing test touched | `requirement-sync` evaluation (D6.6) |
|
|
212
|
+
|
|
213
|
+
Decision extraction recognizes ATX boundaries with 0–3 leading spaces and ignores fenced or indented code. A suspected Setext Decision heading, or an unsupported Setext boundary within an ATX Decision section, yields `unknown`; paragraph/container context is not inferred.
|
|
214
|
+
|
|
215
|
+
- Example: a typo in an ADR's *Context* section triggers only lint + links; the same typo in its *Decision* section is normative.
|
|
216
|
+
- Claimed scope vs diff facts mismatch → claim/evidence contradiction (#320 D3), only where the diff supports it; visible, never a lock.
|
|
217
|
+
- Commit still requires existing workflow authorization; no automatic commit.
|
|
218
|
+
|
|
219
|
+
## D6.6 — Event-driven maintenance (Decided)
|
|
220
|
+
|
|
221
|
+
**`requirement-sync` detection** (builds on D6.2: tests cite REQ IDs):
|
|
222
|
+
|
|
223
|
+
| Observation | Disposition |
|
|
224
|
+
| --- | --- |
|
|
225
|
+
| A test citing `REQ-X` is added or its assertions change | **Candidate signal**, not proof → **MUST** update/supersede REQ-X in the PRD in the same change, or record a structured `no-req-change` (reason + cited evidence, e.g. unchanged acceptance, passing test result) |
|
|
226
|
+
| An existing test's cited REQ identity set is added, removed, or retargeted, or the changed call cannot be associated with its prior identity | Applicability/scope `unknown`, never N/A; retain candidate REQ identities and the test path. If removal leaves no candidate identity, retain the prior REQ ID as a removed identity. A citation-only change is not by itself a `new-test` or `assertion-change` trigger |
|
|
227
|
+
| A legacy file-level REQ tag is added, removed, or retargeted on a modified test file | Applicability/scope `unknown`, never N/A; retain the changed identity and test path, even when stripped comments leave assertion tokens unchanged |
|
|
228
|
+
| A test title changes or reorders REQ IDs while preserving the same cited identity set, or an ordinary comment changes | No trigger → `requirement-sync` N/A |
|
|
229
|
+
| Ordinary comment-only or whitespace-only edit that preserves the cited REQ identity set | Not a trigger → `requirement-sync` N/A |
|
|
230
|
+
| REQ-citing test change whose assertion change cannot be determined | `unknown`; never a fail |
|
|
231
|
+
| Triggered MUST, **attested envelope** (all of the following), cited REQ resolved, **not** revised, **no** valid `no-req-change` waiver | **Observed fail** (`req-sync-no-revision-or-waiver`). Not a Stop hook, lock, or completion policy |
|
|
232
|
+
| Triggered MUST, `complete` inventory but envelope incomplete, mismatched, or unattested | `none` with `req-sync-envelope-unattested`. Never a fail |
|
|
233
|
+
| Attested envelope = `complete` and `waiverInventoryComplete` both `true`; `baseDigest` equal to the baseline digest; `candidateDigest` equal to the digest of the candidate PRD set; `configDigest` present; non-empty cited REQ list | Caller-attested. The derivation copies it and never infers it. Not independent proof that the caller collected the inventory completely |
|
|
234
|
+
| Unsupported or stale `no-req-change` waiver | Unverified (`unsupported-waiver`). It never satisfies the MUST. It does not by itself establish the failure, and an independently attested unmet obligation may still fail |
|
|
235
|
+
| `no-req-change` without adequate evidence | `not-observed` / unverified; never an automatic pass. An invalid waiver is diagnosed and does not satisfy the MUST |
|
|
236
|
+
| Cited REQ missing, ambiguous, or unresolved | `unresolved` with `req-unresolved`; never a pass, never an observed fail. "Ambiguous" means declared in two distinct current logical PRDs. Retained revisions of one PRD resolve to the current effective revision |
|
|
237
|
+
| Incomplete execution record (no command, no provenance, non-integer `exitCode`) | `execution-record-incomplete`; never a pass |
|
|
238
|
+
| Code changes, no REQ-citing test touched | `not-observed` (#320 D3 evidence state), not a failure; diff alone never proves behavior unchanged |
|
|
239
|
+
| Agent claims REQ-X affected, no supporting evidence | Claim/evidence contradiction; reminder, no lock |
|
|
240
|
+
|
|
241
|
+
| Event | Obligation | Strength | Enforced by |
|
|
242
|
+
| --- | --- | --- | --- |
|
|
243
|
+
| REQ touched (above) | `requirement-sync` | MUST | New rule |
|
|
244
|
+
| `describes:` fingerprint drift | Reminder | SHOULD | D5 #4 |
|
|
245
|
+
| Ticket closed | In-repo tickets: `status: done`; regenerate index. `tickets: "tracker"`: no in-repo ticket status is generated or inferred offline | MUST | D5 #1 + D6.3 lint |
|
|
246
|
+
| ADR superseded | Old ADR `status: superseded` | MUST | D6.3 lint |
|
|
247
|
+
| New defect | Goes to tracker or the declared `tickets` path | MUST | Lint reminder when a ticket is added under a `done` phase |
|
|
248
|
+
| Report finished | `final`; `archived` once its work closes | SHOULD | Reminder |
|
|
249
|
+
|
|
250
|
+
- All events are checked at the existing workflow's `verification` step; no standing maintenance loop.
|
|
251
|
+
- Checks are pure and generators deterministic, so reruns are idempotent.
|
|
252
|
+
- `requirement-sync` is the only genuinely new rule; the rest reuse D5 and D6.3 checks.
|
|
253
|
+
|
|
198
254
|
## Packaging
|
|
199
255
|
|
|
200
256
|
Source checkout, Codex plugin and Claude plugin copy whole skill trees. Callers locate `doc-lifecycle.js` and the resolver relative to their own skill directory, never the source-tree root. A to-spec-only install must use the same resolver implementation (copied byte-identically and checked), and a broken shared module is an error, never a silent fallback to older host scanning.
|