@dommaker/harness 1.3.0 → 1.4.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/CHANGELOG.md +8 -0
- package/README.md +0 -2
- package/bin/harness.js +86 -32
- package/dist/cli/command-contract.d.ts +83 -0
- package/dist/cli/command-contract.d.ts.map +1 -0
- package/dist/cli/command-contract.js +66 -0
- package/dist/cli/command-contract.js.map +1 -0
- package/dist/cli/commands/acceptance.d.ts +3 -2
- package/dist/cli/commands/acceptance.d.ts.map +1 -1
- package/dist/cli/commands/acceptance.js +28 -24
- package/dist/cli/commands/acceptance.js.map +1 -1
- package/dist/cli/commands/analyze-sessions.d.ts +2 -1
- package/dist/cli/commands/analyze-sessions.d.ts.map +1 -1
- package/dist/cli/commands/analyze-sessions.js +25 -24
- package/dist/cli/commands/analyze-sessions.js.map +1 -1
- package/dist/cli/commands/check.d.ts +14 -2
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +76 -61
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/command.d.ts +5 -1
- package/dist/cli/commands/command.d.ts.map +1 -1
- package/dist/cli/commands/command.js +26 -17
- package/dist/cli/commands/command.js.map +1 -1
- package/dist/cli/commands/constraints-report.d.ts +2 -1
- package/dist/cli/commands/constraints-report.d.ts.map +1 -1
- package/dist/cli/commands/constraints-report.js +37 -33
- package/dist/cli/commands/constraints-report.js.map +1 -1
- package/dist/cli/commands/constraints-retire.d.ts +6 -5
- package/dist/cli/commands/constraints-retire.d.ts.map +1 -1
- package/dist/cli/commands/constraints-retire.js +50 -52
- package/dist/cli/commands/constraints-retire.js.map +1 -1
- package/dist/cli/commands/constraints.d.ts +2 -1
- package/dist/cli/commands/constraints.d.ts.map +1 -1
- package/dist/cli/commands/constraints.js +10 -27
- package/dist/cli/commands/constraints.js.map +1 -1
- package/dist/cli/commands/contract.d.ts +3 -2
- package/dist/cli/commands/contract.d.ts.map +1 -1
- package/dist/cli/commands/contract.js +45 -42
- package/dist/cli/commands/contract.js.map +1 -1
- package/dist/cli/commands/definitions.d.ts +11 -11
- package/dist/cli/commands/definitions.d.ts.map +1 -1
- package/dist/cli/commands/definitions.js +29 -214
- package/dist/cli/commands/definitions.js.map +1 -1
- package/dist/cli/commands/failure.d.ts +5 -4
- package/dist/cli/commands/failure.d.ts.map +1 -1
- package/dist/cli/commands/failure.js +31 -25
- package/dist/cli/commands/failure.js.map +1 -1
- package/dist/cli/commands/init.d.ts +7 -5
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +147 -211
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/knowledge.d.ts +21 -15
- package/dist/cli/commands/knowledge.d.ts.map +1 -1
- package/dist/cli/commands/knowledge.js +214 -199
- package/dist/cli/commands/knowledge.js.map +1 -1
- package/dist/cli/commands/passes-gate.d.ts +8 -2
- package/dist/cli/commands/passes-gate.d.ts.map +1 -1
- package/dist/cli/commands/passes-gate.js +44 -66
- package/dist/cli/commands/passes-gate.js.map +1 -1
- package/dist/cli/commands/performance.d.ts +2 -1
- package/dist/cli/commands/performance.d.ts.map +1 -1
- package/dist/cli/commands/performance.js +20 -18
- package/dist/cli/commands/performance.js.map +1 -1
- package/dist/cli/commands/posteval-plan.d.ts +5 -1
- package/dist/cli/commands/posteval-plan.d.ts.map +1 -1
- package/dist/cli/commands/posteval-plan.js +26 -15
- package/dist/cli/commands/posteval-plan.js.map +1 -1
- package/dist/cli/commands/release.d.ts +6 -1
- package/dist/cli/commands/release.d.ts.map +1 -1
- package/dist/cli/commands/release.js +69 -59
- package/dist/cli/commands/release.js.map +1 -1
- package/dist/cli/commands/report.d.ts +2 -1
- package/dist/cli/commands/report.d.ts.map +1 -1
- package/dist/cli/commands/report.js +9 -5
- package/dist/cli/commands/report.js.map +1 -1
- package/dist/cli/commands/review.d.ts +3 -2
- package/dist/cli/commands/review.d.ts.map +1 -1
- package/dist/cli/commands/review.js +33 -29
- package/dist/cli/commands/review.js.map +1 -1
- package/dist/cli/commands/sdd.d.ts +2 -1
- package/dist/cli/commands/sdd.d.ts.map +1 -1
- package/dist/cli/commands/sdd.js +7 -5
- package/dist/cli/commands/sdd.js.map +1 -1
- package/dist/cli/commands/security.d.ts +3 -2
- package/dist/cli/commands/security.d.ts.map +1 -1
- package/dist/cli/commands/security.js +29 -26
- package/dist/cli/commands/security.js.map +1 -1
- package/dist/cli/commands/spec-baseline-check.d.ts +2 -1
- package/dist/cli/commands/spec-baseline-check.d.ts.map +1 -1
- package/dist/cli/commands/spec-baseline-check.js +15 -11
- package/dist/cli/commands/spec-baseline-check.js.map +1 -1
- package/dist/cli/commands/spec.d.ts +7 -2
- package/dist/cli/commands/spec.d.ts.map +1 -1
- package/dist/cli/commands/spec.js +61 -51
- package/dist/cli/commands/spec.js.map +1 -1
- package/dist/cli/commands/status.d.ts +2 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +57 -53
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/sync-docs/agents-syncer.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/agents-syncer.js +5 -2
- package/dist/cli/commands/sync-docs/agents-syncer.js.map +1 -1
- package/dist/cli/commands/sync-docs/context-syncer.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/context-syncer.js +3 -2
- package/dist/cli/commands/sync-docs/context-syncer.js.map +1 -1
- package/dist/cli/commands/sync-docs/index.d.ts +2 -1
- package/dist/cli/commands/sync-docs/index.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/index.js +68 -88
- package/dist/cli/commands/sync-docs/index.js.map +1 -1
- package/dist/cli/commands/sync-docs/project-reader.d.ts +6 -1
- package/dist/cli/commands/sync-docs/project-reader.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/project-reader.js +14 -16
- package/dist/cli/commands/sync-docs/project-reader.js.map +1 -1
- package/dist/cli/commands/update-user-model.d.ts +2 -1
- package/dist/cli/commands/update-user-model.d.ts.map +1 -1
- package/dist/cli/commands/update-user-model.js +31 -45
- package/dist/cli/commands/update-user-model.js.map +1 -1
- package/dist/cli/commands/validate.d.ts +4 -3
- package/dist/cli/commands/validate.d.ts.map +1 -1
- package/dist/cli/commands/validate.js +28 -26
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/session-mining/transcript.d.ts +7 -1
- package/dist/cli/session-mining/transcript.d.ts.map +1 -1
- package/dist/cli/session-mining/transcript.js +21 -14
- package/dist/cli/session-mining/transcript.js.map +1 -1
- package/dist/context/session-manager.d.ts.map +1 -1
- package/dist/context/session-manager.js +19 -32
- package/dist/context/session-manager.js.map +1 -1
- package/dist/core/constraints/agent-prompt-renderer.d.ts.map +1 -1
- package/dist/core/constraints/agent-prompt-renderer.js +1 -4
- package/dist/core/constraints/agent-prompt-renderer.js.map +1 -1
- package/dist/core/constraints/capabilities-parser.d.ts +24 -7
- package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
- package/dist/core/constraints/capabilities-parser.js +32 -28
- package/dist/core/constraints/capabilities-parser.js.map +1 -1
- package/dist/core/constraints/capabilities-reconcile.d.ts +67 -0
- package/dist/core/constraints/capabilities-reconcile.d.ts.map +1 -0
- package/dist/core/constraints/capabilities-reconcile.js +105 -0
- package/dist/core/constraints/capabilities-reconcile.js.map +1 -0
- package/dist/core/constraints/checker.d.ts +21 -43
- package/dist/core/constraints/checker.d.ts.map +1 -1
- package/dist/core/constraints/checker.js +64 -115
- package/dist/core/constraints/checker.js.map +1 -1
- package/dist/core/constraints/checkers/capability-sync.d.ts +4 -3
- package/dist/core/constraints/checkers/capability-sync.d.ts.map +1 -1
- package/dist/core/constraints/checkers/capability-sync.js +29 -69
- package/dist/core/constraints/checkers/capability-sync.js.map +1 -1
- package/dist/core/constraints/checkers/context-doc-sync.d.ts +4 -2
- package/dist/core/constraints/checkers/context-doc-sync.d.ts.map +1 -1
- package/dist/core/constraints/checkers/context-doc-sync.js +13 -22
- package/dist/core/constraints/checkers/context-doc-sync.js.map +1 -1
- package/dist/core/constraints/checkers/docs-freshness.d.ts.map +1 -1
- package/dist/core/constraints/checkers/docs-freshness.js +37 -63
- package/dist/core/constraints/checkers/docs-freshness.js.map +1 -1
- package/dist/core/constraints/checkers/governance-presence.d.ts +2 -2
- package/dist/core/constraints/checkers/governance-presence.d.ts.map +1 -1
- package/dist/core/constraints/checkers/governance-presence.js +7 -28
- package/dist/core/constraints/checkers/governance-presence.js.map +1 -1
- package/dist/core/constraints/checkers/no-test-simplification.d.ts.map +1 -1
- package/dist/core/constraints/checkers/no-test-simplification.js +4 -3
- package/dist/core/constraints/checkers/no-test-simplification.js.map +1 -1
- package/dist/core/constraints/checkers/types.d.ts +2 -2
- package/dist/core/constraints/context-builder.d.ts +15 -14
- package/dist/core/constraints/context-builder.d.ts.map +1 -1
- package/dist/core/constraints/context-builder.js +32 -96
- package/dist/core/constraints/context-builder.js.map +1 -1
- package/dist/core/constraints/doc-freshness/runner.d.ts.map +1 -1
- package/dist/core/constraints/doc-freshness/runner.js +2 -1
- package/dist/core/constraints/doc-freshness/runner.js.map +1 -1
- package/dist/core/constraints/git-evidence.d.ts +60 -0
- package/dist/core/constraints/git-evidence.d.ts.map +1 -0
- package/dist/core/constraints/git-evidence.js +88 -0
- package/dist/core/constraints/git-evidence.js.map +1 -0
- package/dist/core/constraints/injection-drift.d.ts +3 -20
- package/dist/core/constraints/injection-drift.d.ts.map +1 -1
- package/dist/core/constraints/injection-drift.js +10 -57
- package/dist/core/constraints/injection-drift.js.map +1 -1
- package/dist/core/constraints/injection-writer.d.ts +113 -0
- package/dist/core/constraints/injection-writer.d.ts.map +1 -0
- package/dist/core/constraints/injection-writer.js +228 -0
- package/dist/core/constraints/injection-writer.js.map +1 -0
- package/dist/core/constraints/usage-report.d.ts +22 -1
- package/dist/core/constraints/usage-report.d.ts.map +1 -1
- package/dist/core/constraints/usage-report.js +27 -20
- package/dist/core/constraints/usage-report.js.map +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/project-config-loader.d.ts +32 -1
- package/dist/core/project-config-loader.d.ts.map +1 -1
- package/dist/core/project-config-loader.js +39 -9
- package/dist/core/project-config-loader.js.map +1 -1
- package/dist/core/validators/passes-gate.d.ts +15 -64
- package/dist/core/validators/passes-gate.d.ts.map +1 -1
- package/dist/core/validators/passes-gate.js +84 -222
- package/dist/core/validators/passes-gate.js.map +1 -1
- package/dist/core/validators/test-output.d.ts +58 -0
- package/dist/core/validators/test-output.d.ts.map +1 -0
- package/dist/core/validators/test-output.js +109 -0
- package/dist/core/validators/test-output.js.map +1 -0
- package/dist/failure/recorder.d.ts +6 -0
- package/dist/failure/recorder.d.ts.map +1 -1
- package/dist/failure/recorder.js +12 -8
- package/dist/failure/recorder.js.map +1 -1
- package/dist/gates/acceptance.d.ts +1 -48
- package/dist/gates/acceptance.d.ts.map +1 -1
- package/dist/gates/acceptance.js +6 -38
- package/dist/gates/acceptance.js.map +1 -1
- package/dist/gates/checker-gate.d.ts.map +1 -1
- package/dist/gates/checker-gate.js +6 -11
- package/dist/gates/checker-gate.js.map +1 -1
- package/dist/gates/command.d.ts.map +1 -1
- package/dist/gates/command.js +10 -22
- package/dist/gates/command.js.map +1 -1
- package/dist/gates/contract.d.ts.map +1 -1
- package/dist/gates/contract.js +22 -61
- package/dist/gates/contract.js.map +1 -1
- package/dist/gates/performance.d.ts.map +1 -1
- package/dist/gates/performance.js +13 -31
- package/dist/gates/performance.js.map +1 -1
- package/dist/gates/review.d.ts.map +1 -1
- package/dist/gates/review.js +21 -53
- package/dist/gates/review.js.map +1 -1
- package/dist/gates/security.d.ts.map +1 -1
- package/dist/gates/security.js +14 -32
- package/dist/gates/security.js.map +1 -1
- package/dist/gates/types.d.ts +28 -5
- package/dist/gates/types.d.ts.map +1 -1
- package/dist/gates/types.js +38 -1
- package/dist/gates/types.js.map +1 -1
- package/dist/hooks/bootstrap.d.ts +2 -0
- package/dist/hooks/bootstrap.d.ts.map +1 -1
- package/dist/hooks/bootstrap.js +5 -2
- package/dist/hooks/bootstrap.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/knowledge/audit.d.ts +7 -2
- package/dist/knowledge/audit.d.ts.map +1 -1
- package/dist/knowledge/audit.js +59 -79
- package/dist/knowledge/audit.js.map +1 -1
- package/dist/knowledge/flywheel-metrics.d.ts +39 -0
- package/dist/knowledge/flywheel-metrics.d.ts.map +1 -0
- package/dist/knowledge/flywheel-metrics.js +47 -0
- package/dist/knowledge/flywheel-metrics.js.map +1 -0
- package/dist/knowledge/import.d.ts.map +1 -1
- package/dist/knowledge/import.js +4 -14
- package/dist/knowledge/import.js.map +1 -1
- package/dist/knowledge/index-generator.d.ts.map +1 -1
- package/dist/knowledge/index-generator.js +17 -14
- package/dist/knowledge/index-generator.js.map +1 -1
- package/dist/knowledge/ingest.d.ts.map +1 -1
- package/dist/knowledge/ingest.js +9 -4
- package/dist/knowledge/ingest.js.map +1 -1
- package/dist/knowledge/migration.d.ts.map +1 -1
- package/dist/knowledge/migration.js +11 -8
- package/dist/knowledge/migration.js.map +1 -1
- package/dist/knowledge/reference-tracker.d.ts.map +1 -1
- package/dist/knowledge/reference-tracker.js +12 -9
- package/dist/knowledge/reference-tracker.js.map +1 -1
- package/dist/knowledge/store.d.ts +15 -0
- package/dist/knowledge/store.d.ts.map +1 -1
- package/dist/knowledge/store.js +59 -10
- package/dist/knowledge/store.js.map +1 -1
- package/dist/monitoring/context-tracker.d.ts.map +1 -1
- package/dist/monitoring/context-tracker.js +11 -20
- package/dist/monitoring/context-tracker.js.map +1 -1
- package/dist/monitoring/index.d.ts +1 -1
- package/dist/monitoring/index.d.ts.map +1 -1
- package/dist/monitoring/index.js +1 -2
- package/dist/monitoring/index.js.map +1 -1
- package/dist/monitoring/trace-analyzer.d.ts +15 -0
- package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
- package/dist/monitoring/trace-analyzer.js +19 -2
- package/dist/monitoring/trace-analyzer.js.map +1 -1
- package/dist/monitoring/traces.d.ts +21 -2
- package/dist/monitoring/traces.d.ts.map +1 -1
- package/dist/monitoring/traces.js +38 -29
- package/dist/monitoring/traces.js.map +1 -1
- package/dist/release/index.d.ts +2 -2
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +1 -5
- package/dist/release/index.js.map +1 -1
- package/dist/sdd/index-generator.js +10 -11
- package/dist/sdd/index-generator.js.map +1 -1
- package/dist/test-setup/project-fixture.d.ts +48 -0
- package/dist/test-setup/project-fixture.d.ts.map +1 -0
- package/dist/test-setup/project-fixture.js +106 -0
- package/dist/test-setup/project-fixture.js.map +1 -0
- package/dist/types/constraint.d.ts +0 -18
- package/dist/types/constraint.d.ts.map +1 -1
- package/dist/types/constraint.js.map +1 -1
- package/dist/types/passes-gate.d.ts +10 -25
- package/dist/types/passes-gate.d.ts.map +1 -1
- package/dist/types/project-config.d.ts +1 -1
- package/dist/types/session.d.ts +6 -5
- package/dist/types/session.d.ts.map +1 -1
- package/dist/utils/exec.d.ts +10 -0
- package/dist/utils/exec.d.ts.map +1 -1
- package/dist/utils/exec.js +12 -0
- package/dist/utils/exec.js.map +1 -1
- package/dist/utils/file-walk.d.ts +9 -1
- package/dist/utils/file-walk.d.ts.map +1 -1
- package/dist/utils/file-walk.js +10 -1
- package/dist/utils/file-walk.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +73 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +141 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/jsonl.d.ts +92 -0
- package/dist/utils/jsonl.d.ts.map +1 -0
- package/dist/utils/jsonl.js +166 -0
- package/dist/utils/jsonl.js.map +1 -0
- package/dist/utils/package-version.d.ts +16 -0
- package/dist/utils/package-version.d.ts.map +1 -0
- package/dist/utils/package-version.js +63 -0
- package/dist/utils/package-version.js.map +1 -0
- package/package.json +1 -1
- package/src/CONTEXT.md +7 -2
- package/src/__tests__/acceptance-gate.test.ts +3 -1
- package/src/__tests__/checker-extra.test.ts +7 -1218
- package/src/__tests__/context-files-resolution.test.ts +116 -0
- package/src/__tests__/effective-constraints.test.ts +10 -13
- package/src/__tests__/exec.test.ts +35 -1
- package/src/__tests__/layering.test.ts +152 -0
- package/src/__tests__/passes-gate-extra.test.ts +0 -145
- package/src/__tests__/passes-gate.test.ts +142 -106
- package/src/__tests__/skip-semantics.test.ts +5 -9
- package/src/cli/__tests__/command-contract.test.ts +170 -0
- package/src/cli/command-contract.ts +108 -0
- package/src/cli/commands/CONTEXT.md +22 -7
- package/src/cli/commands/__tests__/acceptance.test.ts +40 -33
- package/src/cli/commands/__tests__/analyze-sessions.test.ts +35 -29
- package/src/cli/commands/__tests__/bin-exit-mapping.test.ts +101 -0
- package/src/cli/commands/__tests__/check-drift.test.ts +27 -34
- package/src/cli/commands/__tests__/check-skip-output.test.ts +21 -24
- package/src/cli/commands/__tests__/check.test.ts +378 -382
- package/src/cli/commands/__tests__/command.test.ts +85 -70
- package/src/cli/commands/__tests__/constraints-report.test.ts +100 -71
- package/src/cli/commands/__tests__/constraints-retire.test.ts +152 -95
- package/src/cli/commands/__tests__/contract.test.ts +27 -34
- package/src/cli/commands/__tests__/failure.test.ts +31 -34
- package/src/cli/commands/__tests__/init-injection.test.ts +58 -28
- package/src/cli/commands/__tests__/init.test.ts +77 -48
- package/src/cli/commands/__tests__/knowledge-flywheel-consistency.test.ts +108 -0
- package/src/cli/commands/__tests__/knowledge.test.ts +69 -43
- package/src/cli/commands/__tests__/passes-gate.test.ts +43 -45
- package/src/cli/commands/__tests__/performance.test.ts +22 -23
- package/src/cli/commands/__tests__/posteval-plan.test.ts +39 -38
- package/src/cli/commands/__tests__/project-path-anchoring.test.ts +157 -0
- package/src/cli/commands/__tests__/project-path-convention.test.ts +169 -0
- package/src/cli/commands/__tests__/registry.test.ts +69 -35
- package/src/cli/commands/__tests__/release.test.ts +209 -80
- package/src/cli/commands/__tests__/report-extra.test.ts +16 -16
- package/src/cli/commands/__tests__/report.test.ts +25 -25
- package/src/cli/commands/__tests__/review.test.ts +33 -31
- package/src/cli/commands/__tests__/security.test.ts +23 -27
- package/src/cli/commands/__tests__/spec-baseline-check.test.ts +20 -20
- package/src/cli/commands/__tests__/spec.test.ts +41 -29
- package/src/cli/commands/__tests__/status-extra.test.ts +18 -18
- package/src/cli/commands/__tests__/status-skipped-lines.test.ts +72 -0
- package/src/cli/commands/__tests__/status.test.ts +34 -34
- package/src/cli/commands/__tests__/sync-docs-agents.test.ts +77 -78
- package/src/cli/commands/__tests__/sync-docs.test.ts +72 -74
- package/src/cli/commands/__tests__/update-user-model.test.ts +62 -33
- package/src/cli/commands/__tests__/validate.test.ts +27 -29
- package/src/cli/commands/acceptance.ts +35 -24
- package/src/cli/commands/analyze-sessions.ts +25 -24
- package/src/cli/commands/check.ts +88 -65
- package/src/cli/commands/command.ts +30 -17
- package/src/cli/commands/constraints-report.ts +37 -34
- package/src/cli/commands/constraints-retire.ts +58 -55
- package/src/cli/commands/constraints.ts +10 -27
- package/src/cli/commands/contract.ts +51 -42
- package/src/cli/commands/definitions.ts +36 -222
- package/src/cli/commands/failure.ts +33 -26
- package/src/cli/commands/init.ts +166 -220
- package/src/cli/commands/knowledge.ts +225 -203
- package/src/cli/commands/passes-gate.ts +58 -68
- package/src/cli/commands/performance.ts +23 -18
- package/src/cli/commands/posteval-plan.ts +29 -15
- package/src/cli/commands/release.ts +70 -59
- package/src/cli/commands/report.ts +9 -5
- package/src/cli/commands/review.ts +39 -29
- package/src/cli/commands/sdd.ts +7 -5
- package/src/cli/commands/security.ts +35 -26
- package/src/cli/commands/spec-baseline-check.ts +16 -11
- package/src/cli/commands/spec.ts +66 -53
- package/src/cli/commands/status.ts +59 -53
- package/src/cli/commands/sync-docs/agents-syncer.ts +5 -2
- package/src/cli/commands/sync-docs/context-syncer.ts +3 -2
- package/src/cli/commands/sync-docs/index.ts +73 -100
- package/src/cli/commands/sync-docs/project-reader.ts +17 -18
- package/src/cli/commands/update-user-model.ts +33 -45
- package/src/cli/commands/validate.ts +31 -25
- package/src/cli/session-mining/__tests__/transcript.test.ts +118 -0
- package/src/cli/session-mining/transcript.ts +26 -8
- package/src/context/session-manager.ts +19 -33
- package/src/core/CONTEXT.md +9 -6
- package/src/core/constraints/__tests__/capabilities-reconcile.test.ts +200 -0
- package/src/core/constraints/__tests__/capability-counts.test.ts +94 -0
- package/src/core/constraints/__tests__/git-evidence.test.ts +208 -0
- package/src/core/constraints/__tests__/injection-drift.test.ts +3 -10
- package/src/core/constraints/__tests__/injection-writer.test.ts +231 -0
- package/src/core/constraints/__tests__/trace-injection.test.ts +71 -0
- package/src/core/constraints/__tests__/usage-report.test.ts +112 -0
- package/src/core/constraints/agent-prompt-renderer.ts +2 -6
- package/src/core/constraints/capabilities-parser.ts +53 -35
- package/src/core/constraints/capabilities-reconcile.ts +166 -0
- package/src/core/constraints/checker.ts +75 -130
- package/src/core/constraints/checkers/__tests__/capability-sync.test.ts +214 -0
- package/src/core/constraints/checkers/__tests__/context-doc-sync.test.ts +77 -0
- package/src/core/constraints/checkers/__tests__/docs-freshness.test.ts +117 -0
- package/src/{__tests__ → core/constraints/checkers/__tests__}/governance-presence.test.ts +83 -9
- package/src/core/constraints/checkers/__tests__/iron-flags.test.ts +50 -0
- package/src/core/constraints/checkers/__tests__/no-bypass-checkpoint.test.ts +76 -0
- package/src/{__tests__ → core/constraints/checkers/__tests__}/no-hardcoded-credentials.test.ts +4 -3
- package/src/core/constraints/checkers/__tests__/no-test-simplification.test.ts +58 -0
- package/src/core/constraints/checkers/__tests__/three-state-consistency.test.ts +145 -0
- package/src/core/constraints/checkers/capability-sync.ts +29 -88
- package/src/core/constraints/checkers/context-doc-sync.ts +15 -25
- package/src/core/constraints/checkers/docs-freshness.ts +40 -69
- package/src/core/constraints/checkers/governance-presence.ts +7 -25
- package/src/core/constraints/checkers/no-test-simplification.ts +4 -3
- package/src/core/constraints/checkers/types.ts +2 -2
- package/src/core/constraints/context-builder.ts +39 -91
- package/src/core/constraints/doc-freshness/runner.ts +2 -1
- package/src/core/constraints/git-evidence.ts +120 -0
- package/src/core/constraints/injection-drift.ts +13 -60
- package/src/core/constraints/injection-writer.ts +212 -0
- package/src/core/constraints/usage-report.ts +36 -17
- package/src/core/index.ts +4 -2
- package/src/core/project-config-loader.ts +49 -9
- package/src/core/validators/__tests__/passes-gate.test.ts +2 -56
- package/src/core/validators/__tests__/test-output.test.ts +372 -0
- package/src/core/validators/passes-gate.ts +86 -248
- package/src/core/validators/test-output.ts +128 -0
- package/src/failure/__tests__/recorder.test.ts +168 -0
- package/src/failure/recorder.ts +12 -10
- package/src/gates/CONTEXT.md +6 -3
- package/src/gates/__tests__/acceptance-types-single-source.test.ts +68 -0
- package/src/gates/__tests__/acceptance.test.ts +4 -86
- package/src/gates/__tests__/effective-gates.test.ts +3 -8
- package/src/gates/__tests__/test-verdict-consistency.test.ts +140 -0
- package/src/gates/acceptance.ts +19 -84
- package/src/gates/checker-gate.ts +8 -7
- package/src/gates/command.ts +10 -16
- package/src/gates/contract.ts +22 -61
- package/src/gates/performance.ts +10 -22
- package/src/gates/review.ts +21 -41
- package/src/gates/security.ts +10 -22
- package/src/gates/types.ts +70 -5
- package/src/hooks/CONTEXT.md +1 -1
- package/src/hooks/bootstrap.ts +5 -2
- package/src/index.ts +0 -4
- package/src/knowledge/CONTEXT.md +8 -3
- package/src/knowledge/__tests__/audit-labels.test.ts +44 -0
- package/src/knowledge/__tests__/flywheel-metrics.test.ts +135 -0
- package/src/knowledge/__tests__/import.test.ts +44 -0
- package/src/knowledge/__tests__/index-generator.test.ts +53 -0
- package/src/knowledge/__tests__/ingest.test.ts +85 -0
- package/src/knowledge/__tests__/migration.test.ts +47 -0
- package/src/knowledge/__tests__/reference-tracker.test.ts +16 -0
- package/src/knowledge/__tests__/store.test.ts +194 -0
- package/src/knowledge/audit.ts +67 -71
- package/src/knowledge/flywheel-metrics.ts +71 -0
- package/src/knowledge/import.ts +4 -18
- package/src/knowledge/index-generator.ts +19 -14
- package/src/knowledge/ingest.ts +9 -4
- package/src/knowledge/migration.ts +11 -8
- package/src/knowledge/reference-tracker.ts +12 -8
- package/src/knowledge/store.ts +64 -11
- package/src/monitoring/CONTEXT.md +8 -3
- package/src/monitoring/__tests__/skipped-lines-report.test.ts +178 -0
- package/src/monitoring/__tests__/traces.test.ts +57 -0
- package/src/monitoring/context-tracker.ts +11 -23
- package/src/monitoring/index.ts +1 -1
- package/src/monitoring/trace-analyzer.ts +21 -2
- package/src/monitoring/traces.ts +39 -36
- package/src/release/CONTEXT.md +1 -0
- package/src/release/__tests__/barrel.test.ts +60 -0
- package/src/release/index.ts +2 -13
- package/src/sdd/__tests__/index-generator.test.ts +71 -0
- package/src/sdd/index-generator.ts +9 -9
- package/src/test-setup/__tests__/project-fixture.test.ts +178 -0
- package/src/test-setup/project-fixture.ts +87 -0
- package/src/tools/CONTEXT.md +6 -0
- package/src/tools/__tests__/registry.test.ts +221 -0
- package/src/types/__tests__/types.test.ts +4 -5
- package/src/types/constraint.ts +0 -25
- package/src/types/passes-gate.ts +10 -30
- package/src/types/project-config.ts +1 -1
- package/src/types/session.ts +5 -5
- package/src/utils/__tests__/frontmatter.test.ts +206 -0
- package/src/utils/__tests__/jsonl-skip-disposition.test.ts +175 -0
- package/src/utils/__tests__/jsonl.test.ts +187 -0
- package/src/utils/__tests__/package-version.test.ts +97 -0
- package/src/utils/exec.ts +15 -0
- package/src/utils/file-walk.ts +11 -2
- package/src/utils/frontmatter.ts +121 -0
- package/src/utils/jsonl.ts +167 -0
- package/src/utils/package-version.ts +27 -0
- package/dist/cli/commands/doc-freshness-check.d.ts +0 -53
- package/dist/cli/commands/doc-freshness-check.d.ts.map +0 -1
- package/dist/cli/commands/doc-freshness-check.js +0 -352
- package/dist/cli/commands/doc-freshness-check.js.map +0 -1
- package/dist/types/index.d.ts +0 -14
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -39
- package/dist/types/index.js.map +0 -1
- package/src/__tests__/long-running.test.ts +0 -17
- package/src/__tests__/passes-gate-extension.test.ts +0 -151
- package/src/cli/commands/__tests__/doc-freshness-check.test.ts +0 -168
- package/src/cli/commands/doc-freshness-check.ts +0 -386
- package/src/spec/CONTEXT.md +0 -11
- package/src/types/index.ts +0 -47
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 治理注入段落点写入器(架构评审候选1,ADR-0011)
|
|
3
|
+
*
|
|
4
|
+
* 「按渲染 body 替换标记区间 + 尾换行规一」的切片数学此前手抄 4 份
|
|
5
|
+
* (init.ts 三个 writer / constraints-retire 一份),落点路由读写两侧各抄一份。
|
|
6
|
+
* 本模块是唯一 writer:init/retire 退化为「渲染 body + 调 writer」。
|
|
7
|
+
*
|
|
8
|
+
* 形状两种(排版约定不同,非"算哪些"的差异,故合法分叉):
|
|
9
|
+
* - replaceStandaloneRange:区间独立成节,END 标记后折叠为恰好一个空行
|
|
10
|
+
* (CLAUDE.md 约束段 / Output Style 段 / retire 注入段同步)
|
|
11
|
+
* - replaceEnclosedRange:区间后紧跟外层收口标记(AGENTS.md PRESERVE 段内
|
|
12
|
+
* 的 HARNESS_CONSTRAINTS 区间)——恰好剥一个换行,手写余文原样落回
|
|
13
|
+
*
|
|
14
|
+
* 半标记守护:单边缺失或顺序颠倒 → 'half',拒写(旧实现此时或追加出双份
|
|
15
|
+
* 正本或产生乱序切片,属二次损坏路径,收紧为告警交人工,见 ADR-0011)。
|
|
16
|
+
*
|
|
17
|
+
* 落点路由同规则一份:
|
|
18
|
+
* - resolveInjectionTarget:读侧(漂移检测/retire 同步)——CLAUDE.md 有完整
|
|
19
|
+
* 标记段优先(旧模型仓豁免),否则 AGENTS.md(新模型仓住 PRESERVE 段内)
|
|
20
|
+
* - resolveGovernanceLanding:写侧(init 落点选择)——额外承认 CLAUDE.md
|
|
21
|
+
* 无标记的 `## Governance Rules` 旧块(续写不制造双份正本)
|
|
22
|
+
*
|
|
23
|
+
* 探测/判定同住本模块(#83,ADR-0011 补注:收口范围含探测器,不只写器)——
|
|
24
|
+
* 「这份文档里有没有治理契约 / 有几个正本标题」此前手抄 4 份且正则已漂移,
|
|
25
|
+
* 见文末 GOVERNANCE_HEADING / hasGovernanceContract / countGovernanceHeadings /
|
|
26
|
+
* hasPreserveBlock。
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import * as fs from 'fs';
|
|
30
|
+
import * as path from 'path';
|
|
31
|
+
import {
|
|
32
|
+
CONSTRAINTS_START_MARKER,
|
|
33
|
+
CONSTRAINTS_END_MARKER,
|
|
34
|
+
} from './injection-renderer';
|
|
35
|
+
|
|
36
|
+
/** 注入段落点文件名(检测顺序即路由优先级:旧模型仓 CLAUDE.md 优先) */
|
|
37
|
+
export const INJECTION_FILES = ['CLAUDE.md', 'AGENTS.md'] as const;
|
|
38
|
+
export type InjectionFile = (typeof INJECTION_FILES)[number];
|
|
39
|
+
|
|
40
|
+
/** 标记区间替换结果 */
|
|
41
|
+
export type MarkerWrite =
|
|
42
|
+
| { kind: 'updated'; content: string }
|
|
43
|
+
| { kind: 'absent' }
|
|
44
|
+
| { kind: 'half' };
|
|
45
|
+
|
|
46
|
+
/** 完整标记块的内容切分(inner 含首尾标记行外的全部文本,含原换行) */
|
|
47
|
+
export interface MarkerBlock {
|
|
48
|
+
before: string;
|
|
49
|
+
inner: string;
|
|
50
|
+
/** 后标记之后的原文(未规一) */
|
|
51
|
+
after: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function readIfExists(filePath: string): string | null {
|
|
55
|
+
try {
|
|
56
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
57
|
+
return typeof content === 'string' ? content : null;
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** 定位完整标记对:两标记俱在且顺序正确 */
|
|
64
|
+
function findPair(content: string, begin: string, end: string): { startIdx: number; endIdx: number } | 'absent' | 'half' {
|
|
65
|
+
const startIdx = content.indexOf(begin);
|
|
66
|
+
const endIdx = content.indexOf(end);
|
|
67
|
+
if (startIdx === -1 && endIdx === -1) return 'absent';
|
|
68
|
+
if (startIdx === -1 || endIdx === -1 || endIdx < startIdx) return 'half';
|
|
69
|
+
return { startIdx, endIdx };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 切出完整标记块(before + begin + inner + end + after)。
|
|
74
|
+
* 'absent' = 两俱无;'half' = 残缺/乱序,拒切。
|
|
75
|
+
*/
|
|
76
|
+
export function cutMarkerBlock(content: string, begin: string, end: string): MarkerBlock | 'absent' | 'half' {
|
|
77
|
+
const pair = findPair(content, begin, end);
|
|
78
|
+
if (pair === 'absent' || pair === 'half') return pair;
|
|
79
|
+
return {
|
|
80
|
+
before: content.slice(0, pair.startIdx),
|
|
81
|
+
inner: content.slice(pair.startIdx + begin.length, pair.endIdx),
|
|
82
|
+
after: content.slice(pair.endIdx + end.length),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 替换独立成节的标记区间:body 为含首尾标记的完整替换文本(以换行结尾),
|
|
88
|
+
* 区间后文剥除全部前导换行、以恰好一个空行相接(幂等:重复替换结果稳定)。
|
|
89
|
+
*/
|
|
90
|
+
export function replaceStandaloneRange(content: string, begin: string, end: string, body: string): MarkerWrite {
|
|
91
|
+
const pair = findPair(content, begin, end);
|
|
92
|
+
if (pair === 'absent' || pair === 'half') return { kind: pair };
|
|
93
|
+
const after = content.slice(pair.endIdx + end.length).replace(/^\n+/, '');
|
|
94
|
+
return {
|
|
95
|
+
kind: 'updated',
|
|
96
|
+
content: content.slice(0, pair.startIdx) + body + (after ? '\n' + after : ''),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 替换后跟外层收口标记的区间:body 含首尾标记且以换行结尾(收口标记落自己行),
|
|
102
|
+
* 区间后文恰好剥一个换行(外层标记拼接位),其余手写余文原样保留。
|
|
103
|
+
*/
|
|
104
|
+
export function replaceEnclosedRange(content: string, begin: string, end: string, body: string): MarkerWrite {
|
|
105
|
+
const pair = findPair(content, begin, end);
|
|
106
|
+
if (pair === 'absent' || pair === 'half') return { kind: pair };
|
|
107
|
+
const tail = content.slice(pair.endIdx + end.length).replace(/^\n/, '');
|
|
108
|
+
return {
|
|
109
|
+
kind: 'updated',
|
|
110
|
+
content: content.slice(0, pair.startIdx) + body + tail,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 读侧路由:定位含完整 HARNESS_CONSTRAINTS 标记段的文件(studio #307)。
|
|
116
|
+
* detectInjectionDrift 与 retire 注入段同步共用。
|
|
117
|
+
*/
|
|
118
|
+
export function resolveInjectionTarget(
|
|
119
|
+
projectRoot: string
|
|
120
|
+
): { file: InjectionFile; content: string; startIdx: number; endIdx: number } | null {
|
|
121
|
+
for (const file of INJECTION_FILES) {
|
|
122
|
+
const content = readIfExists(path.join(projectRoot, file));
|
|
123
|
+
if (content === null) continue;
|
|
124
|
+
const startIdx = content.indexOf(CONSTRAINTS_START_MARKER);
|
|
125
|
+
const endIdx = content.indexOf(CONSTRAINTS_END_MARKER);
|
|
126
|
+
if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
|
|
127
|
+
return { file, content, startIdx, endIdx };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 写侧路由(init 落点选择,原 setupGovernanceConstraints 内联判定收于此):
|
|
135
|
+
* CLAUDE.md 有约束标记段或有旧版 `## Governance Rules` 块 → 续写 CLAUDE.md
|
|
136
|
+
* (旧模型仓豁免,不制造双份正本);否则 AGENTS.md PRESERVE:governance。
|
|
137
|
+
*/
|
|
138
|
+
export function resolveGovernanceLanding(
|
|
139
|
+
projectRoot: string
|
|
140
|
+
): { target: 'claude-md' | 'agents-md'; claudeContent: string | null } {
|
|
141
|
+
const claudeContent = readIfExists(path.join(projectRoot, 'CLAUDE.md'));
|
|
142
|
+
if (claudeContent !== null && hasGovernanceContract(claudeContent)) {
|
|
143
|
+
return { target: 'claude-md', claudeContent };
|
|
144
|
+
}
|
|
145
|
+
return { target: 'agents-md', claudeContent };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* 治理正本标题字面量(单一来源,#83):init 的标题写点与下列两个判定谓词
|
|
150
|
+
* 都由它派生,仓内不再本地拼写。字面量无正则元字符,可直接拼入 RegExp。
|
|
151
|
+
*
|
|
152
|
+
* 两谓词回答两个问题,**共享字面量而非共享正则**(triage 裁决 2026-09-02):
|
|
153
|
+
* 强行合一要么在场守护 fail-open 失效(取严格),要么重复计数引入无行尾
|
|
154
|
+
* 锚定的误报(取宽松)。
|
|
155
|
+
*/
|
|
156
|
+
export const GOVERNANCE_HEADING = '## Governance Rules';
|
|
157
|
+
|
|
158
|
+
/** 标题文本(去 `## ` 前缀),宽松谓词按 `##` + 任意空白 + 此文本匹配 */
|
|
159
|
+
const GOVERNANCE_HEADING_TEXT = GOVERNANCE_HEADING.replace(/^##\s+/, '');
|
|
160
|
+
|
|
161
|
+
/** 宽松标题正则:容忍 `## Governance Rules` 双空格等排版漂移 */
|
|
162
|
+
const GOVERNANCE_HEADING_LOOSE_RE = new RegExp(`^##\\s+${GOVERNANCE_HEADING_TEXT}`, 'm');
|
|
163
|
+
|
|
164
|
+
/** 严格标题正则:精确拼写 + 行尾锚定(行尾仅容忍空白) */
|
|
165
|
+
const GOVERNANCE_HEADING_STRICT_RE = new RegExp(`^${GOVERNANCE_HEADING}[ \\t]*$`, 'gm');
|
|
166
|
+
|
|
167
|
+
/** 约束标记裸文本(去注释壳),宽松谓词按「标记文本在场」判定,容忍壳残缺 */
|
|
168
|
+
const CONSTRAINTS_START_TEXT = CONSTRAINTS_START_MARKER.replace(/^<!--\s*|\s*-->$/g, '');
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* 宽松谓词:内容里是否有治理契约在场——标题宽松匹配或 HARNESS 约束标记
|
|
172
|
+
* 文本在场即算。fail-open 偏向:排版漂移宁可信其有,漏报「约束正本静默
|
|
173
|
+
* 丢失」的代价高于误报。消费方:governance_presence / sync-docs 治理计数 /
|
|
174
|
+
* init 落点路由(#83)。
|
|
175
|
+
*/
|
|
176
|
+
export function hasGovernanceContract(content: string): boolean {
|
|
177
|
+
return GOVERNANCE_HEADING_LOOSE_RE.test(content) || content.includes(CONSTRAINTS_START_TEXT);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* 严格计数:全文统计治理标题数(精确拼写 + 行尾锚定),drift 重复章节
|
|
182
|
+
* 检测专用。宽松变体(如双空格)不计入——在场判定与正本计数是两个问题,
|
|
183
|
+
* 见 GOVERNANCE_HEADING。
|
|
184
|
+
*/
|
|
185
|
+
export function countGovernanceHeadings(content: string): number {
|
|
186
|
+
return (content.match(GOVERNANCE_HEADING_STRICT_RE) ?? []).length;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* PRESERVE 标记块存在性判定:块存在且块体非空(governance_presence 在场
|
|
191
|
+
* 守护消费,#83 收编其手写切片)。标记契约与 sync-docs/preserve-block 一致:
|
|
192
|
+
* 首尾标记均须独占一行——开始标记行首锚定(行尾仅空白),结束标记行 trim
|
|
193
|
+
* 后等于标记文本。结束标记嵌在行中 / 缺失 / 乱序均为畸形块 → false,在场
|
|
194
|
+
* 守护按契约丢失报警(原 presence「行中结束标记也算在场」显式收紧,#83)。
|
|
195
|
+
* name 仅允许字母/数字/下划线/连字符(PRESERVE 命名约定,调用方传常量段名)。
|
|
196
|
+
*/
|
|
197
|
+
export function hasPreserveBlock(content: string, name: string): boolean {
|
|
198
|
+
const beginMarker = `<!-- PRESERVE:${name} -->`;
|
|
199
|
+
const endMarker = `<!-- /PRESERVE:${name} -->`;
|
|
200
|
+
const lines = content.split('\n');
|
|
201
|
+
const begin = lines.findIndex(line => line.trimEnd() === beginMarker);
|
|
202
|
+
if (begin === -1) return false;
|
|
203
|
+
let end = -1;
|
|
204
|
+
for (let j = begin + 1; j < lines.length; j++) {
|
|
205
|
+
if (lines[j].trim() === endMarker) {
|
|
206
|
+
end = j;
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (end === -1) return false;
|
|
211
|
+
return lines.slice(begin + 1, end).join('\n').trim().length > 0;
|
|
212
|
+
}
|
|
@@ -13,6 +13,7 @@ import * as path from 'path';
|
|
|
13
13
|
import type { Constraint } from '../../types/constraint';
|
|
14
14
|
import type { ExecutionTrace } from '../../types/trace';
|
|
15
15
|
import { DEFAULT_TRACE_FILE } from '../../types/trace';
|
|
16
|
+
import { readJsonl } from '../../utils/jsonl';
|
|
16
17
|
import { getEffectiveConstraints, lintEffectiveConfig } from '../effective-constraints';
|
|
17
18
|
import type { EffectiveConfigLint } from '../effective-constraints';
|
|
18
19
|
|
|
@@ -67,6 +68,14 @@ export interface RetireCandidate {
|
|
|
67
68
|
reason: string;
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
/** 候选种类的呈现名(constraints report / retire 共用) */
|
|
72
|
+
export const CANDIDATE_KIND_LABEL: Record<RetireCandidateKind, string> = {
|
|
73
|
+
zero_trigger: '零触发',
|
|
74
|
+
unevaluable: '不可评估',
|
|
75
|
+
high_noise: '高噪',
|
|
76
|
+
zero_intercept: '零拦截',
|
|
77
|
+
};
|
|
78
|
+
|
|
70
79
|
/**
|
|
71
80
|
* 候选诊断阈值(CLI 可覆盖)
|
|
72
81
|
*/
|
|
@@ -99,27 +108,36 @@ export interface ConstraintsUsageReport {
|
|
|
99
108
|
lint: EffectiveConfigLint;
|
|
100
109
|
/** trace 文件是否存在 */
|
|
101
110
|
traceFileExists: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* trace 文件被跳过的坏行数(harness#100,与 `traceFileExists` 同一降级维度)
|
|
113
|
+
*
|
|
114
|
+
* 恒有值,0 = 无损坏。文件级口径:坏行没有 timestamp,归不进任何统计窗口。
|
|
115
|
+
*/
|
|
116
|
+
skippedLines: number;
|
|
102
117
|
}
|
|
103
118
|
|
|
104
119
|
/**
|
|
105
|
-
* 读取项目 traces.log
|
|
120
|
+
* 读取项目 traces.log 并带出坏行计数(只读,harness#100 报告入口)
|
|
121
|
+
*
|
|
122
|
+
* 坏行策略:skip(原语义不变——report 只读,不因单行损坏失败);
|
|
123
|
+
* 计数去向:透传——`skippedLines` 随本方法返回,进 `ConstraintsUsageReport.skippedLines`,
|
|
124
|
+
* 消费面为 `constraints report` 的文本行 / `--json` 字段 / `--export` 摘要。
|
|
125
|
+
*/
|
|
126
|
+
export function readProjectTracesReport(projectRoot: string): { traces: ExecutionTrace[]; skippedLines: number } {
|
|
127
|
+
const { records, skippedLines } = readJsonl<ExecutionTrace>(
|
|
128
|
+
path.join(projectRoot, DEFAULT_TRACE_FILE),
|
|
129
|
+
'skip'
|
|
130
|
+
);
|
|
131
|
+
return { traces: records, skippedLines };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 读取项目 traces.log(只读)
|
|
136
|
+
*
|
|
137
|
+
* 兼容签名:只返回记录数组、丢坏行计数,需要计数的消费方走 `readProjectTracesReport()`。
|
|
106
138
|
*/
|
|
107
139
|
export function readProjectTraces(projectRoot: string): ExecutionTrace[] {
|
|
108
|
-
|
|
109
|
-
if (!fs.existsSync(tracePath)) return [];
|
|
110
|
-
|
|
111
|
-
const content = fs.readFileSync(tracePath, 'utf-8');
|
|
112
|
-
const traces: ExecutionTrace[] = [];
|
|
113
|
-
for (const line of content.split('\n')) {
|
|
114
|
-
const trimmed = line.trim();
|
|
115
|
-
if (!trimmed) continue;
|
|
116
|
-
try {
|
|
117
|
-
traces.push(JSON.parse(trimmed) as ExecutionTrace);
|
|
118
|
-
} catch {
|
|
119
|
-
// 坏行跳过(report 只读,不因单行损坏失败)
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return traces;
|
|
140
|
+
return readProjectTracesReport(projectRoot).traces;
|
|
123
141
|
}
|
|
124
142
|
|
|
125
143
|
/**
|
|
@@ -234,7 +252,7 @@ export function buildConstraintsUsageReport(
|
|
|
234
252
|
const activePromptIds = effective.filter(c => c.kind === 'prompt').map(c => c.id);
|
|
235
253
|
|
|
236
254
|
const tracePath = path.join(projectRoot, DEFAULT_TRACE_FILE);
|
|
237
|
-
const traces =
|
|
255
|
+
const { traces, skippedLines } = readProjectTracesReport(projectRoot);
|
|
238
256
|
const usage = collectUsageByConstraint(traces);
|
|
239
257
|
|
|
240
258
|
const stats = checkConstraints.map(c => toStats(c.id, c.level, usage.get(c.id)));
|
|
@@ -247,5 +265,6 @@ export function buildConstraintsUsageReport(
|
|
|
247
265
|
activePromptIds,
|
|
248
266
|
lint,
|
|
249
267
|
traceFileExists: fs.existsSync(tracePath),
|
|
268
|
+
skippedLines,
|
|
250
269
|
};
|
|
251
270
|
}
|
package/src/core/index.ts
CHANGED
|
@@ -84,13 +84,15 @@ export type {
|
|
|
84
84
|
SpecType,
|
|
85
85
|
} from '../types/spec';
|
|
86
86
|
|
|
87
|
-
//
|
|
87
|
+
// 项目配置加载器(governance 段读取一律经访问器,禁止消费方手写钻取)
|
|
88
88
|
export {
|
|
89
89
|
ProjectConfigLoader,
|
|
90
90
|
loadRawProjectConfig,
|
|
91
|
+
getGovernanceConfig,
|
|
92
|
+
resolveContextFiles,
|
|
91
93
|
getCapabilitiesMode,
|
|
92
94
|
} from './project-config-loader';
|
|
93
|
-
export type { CapabilitiesMode } from './project-config-loader';
|
|
95
|
+
export type { CapabilitiesMode, ContextFilesResolution } from './project-config-loader';
|
|
94
96
|
|
|
95
97
|
// 生效约束集(ADR-0001:唯一生效集来源)
|
|
96
98
|
export {
|
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
CustomConstraintDefinition,
|
|
15
15
|
MergedConstraintsConfig,
|
|
16
16
|
CapabilitiesConfig,
|
|
17
|
+
GovernanceConfig,
|
|
17
18
|
} from '../types/project-config';
|
|
18
19
|
import { IRON_LAWS, GUIDELINES, PROMPTS } from './constraints/definitions';
|
|
19
20
|
import { PRESETS_BY_NAME, STANDARD_PRESET } from '../presets';
|
|
@@ -78,20 +79,59 @@ export function loadRawProjectConfig(projectPath: string): Record<string, unknow
|
|
|
78
79
|
export type CapabilitiesMode = NonNullable<CapabilitiesConfig['mode']>;
|
|
79
80
|
|
|
80
81
|
/**
|
|
81
|
-
* 读取 governance
|
|
82
|
+
* 读取 governance 段(全仓唯一手写钻取点,工单 84)
|
|
82
83
|
*
|
|
83
|
-
*
|
|
84
|
+
* 基于 loadRawProjectConfig 的进程级 memoize,不引入第二次 yaml 解析。
|
|
85
|
+
* 配置缺失 / 解析失败 / 形状不符时返回 undefined,由调用方按未配置处理。
|
|
84
86
|
*/
|
|
85
|
-
export function
|
|
87
|
+
export function getGovernanceConfig(projectPath: string): GovernanceConfig | undefined {
|
|
86
88
|
try {
|
|
87
89
|
const raw = loadRawProjectConfig(projectPath);
|
|
88
|
-
const governance = raw?.governance
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (mode === 'file' || mode === 'module' || mode === 'listing') return mode;
|
|
90
|
+
const governance = raw?.governance;
|
|
91
|
+
if (governance === null || typeof governance !== 'object') return undefined;
|
|
92
|
+
return governance as GovernanceConfig;
|
|
92
93
|
} catch {
|
|
93
|
-
|
|
94
|
+
return undefined;
|
|
94
95
|
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* governance.context_files 三态分辨率(工单 84 triage 裁决口径)
|
|
100
|
+
*
|
|
101
|
+
* - unconfigured:段缺失 / enabled 为假 / 解析失败——约定未采用
|
|
102
|
+
* - enabled-empty:enabled 但 required_dirs 缺失、非数组、含非字符串项或空——
|
|
103
|
+
* 约定已立但无可用目标
|
|
104
|
+
* - enabled:enabled 且 required_dirs 为非空字符串数组——约定有效
|
|
105
|
+
*/
|
|
106
|
+
export type ContextFilesResolution =
|
|
107
|
+
| { state: 'unconfigured' }
|
|
108
|
+
| { state: 'enabled-empty' }
|
|
109
|
+
| { state: 'enabled'; dirs: string[] };
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* 分辨 governance.context_files 三态(语义见 ContextFilesResolution)
|
|
113
|
+
*
|
|
114
|
+
* 消费方约定:约束 checker 对前两态一律 skip(与 ADR-0001 存在性探测同构);
|
|
115
|
+
* init / 扫描类工具流的自动探测回落保留在调用方,不进本访问器。
|
|
116
|
+
* 元素类型在此收口:脏配置(如 required_dirs: [1])不得流入调用方 path.join。
|
|
117
|
+
*/
|
|
118
|
+
export function resolveContextFiles(projectPath: string): ContextFilesResolution {
|
|
119
|
+
const contextFiles = getGovernanceConfig(projectPath)?.context_files;
|
|
120
|
+
if (!contextFiles?.enabled) return { state: 'unconfigured' };
|
|
121
|
+
const dirs = contextFiles.required_dirs;
|
|
122
|
+
if (!Array.isArray(dirs) || dirs.length === 0) return { state: 'enabled-empty' };
|
|
123
|
+
if (!dirs.every(dir => typeof dir === 'string')) return { state: 'enabled-empty' };
|
|
124
|
+
return { state: 'enabled', dirs };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* 读取 governance.capabilities.mode(缺省 'file',向后兼容)
|
|
129
|
+
*
|
|
130
|
+
* 配置缺失/解析失败/取值非法时一律回落 'file'。
|
|
131
|
+
*/
|
|
132
|
+
export function getCapabilitiesMode(projectPath: string): CapabilitiesMode {
|
|
133
|
+
const mode = getGovernanceConfig(projectPath)?.capabilities?.mode;
|
|
134
|
+
if (mode === 'file' || mode === 'module' || mode === 'listing') return mode;
|
|
95
135
|
return 'file';
|
|
96
136
|
}
|
|
97
137
|
|
|
@@ -228,7 +268,7 @@ export class ProjectConfigLoader {
|
|
|
228
268
|
|
|
229
269
|
// 2. 添加自定义约束(config.yml 禁用的 id 不追加:step 1 已将其
|
|
230
270
|
// 收集进 disabled,custom 在 step 1 时尚未入桶,须在此兜底跳过;
|
|
231
|
-
// 条目带 retired
|
|
271
|
+
// 条目带 retired 元数据的同样不追加——studio#82 D6 退役落点在条目自身)
|
|
232
272
|
for (const [id, customDef] of Object.entries(this.customConstraints)) {
|
|
233
273
|
if (result.disabled.includes(id) || customDef.retired) {
|
|
234
274
|
continue;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tests for passes-gate.ts
|
|
3
3
|
*
|
|
4
|
-
* Priority: test pure logic methods (check
|
|
4
|
+
* Priority: test pure logic methods (check)
|
|
5
5
|
* Skip methods that do real file I/O / exec (setPasses, runTests, runTest, detectTestCommand, etc.)
|
|
6
|
+
* 测试产物解析判定不在此面:见 test-output.test.ts(ADR-0012)
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
import { PassesGate, createPassesGate } from '../passes-gate';
|
|
@@ -67,65 +68,10 @@ describe('PassesGate', () => {
|
|
|
67
68
|
});
|
|
68
69
|
});
|
|
69
70
|
|
|
70
|
-
describe('extension management', () => {
|
|
71
|
-
it('registerExtension adds an extension', () => {
|
|
72
|
-
const gate = createPassesGate();
|
|
73
|
-
const ext = { name: 'e2e', run: async () => ({ passed: true, command: 'e2e' }) };
|
|
74
|
-
gate.registerExtension('e2e', ext);
|
|
75
|
-
expect(gate.getExtensionNames()).toContain('e2e');
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('unregisterExtension removes an extension', () => {
|
|
79
|
-
const gate = createPassesGate();
|
|
80
|
-
const ext = { name: 'e2e', run: async () => ({ passed: true, command: 'e2e' }) };
|
|
81
|
-
gate.registerExtension('e2e', ext);
|
|
82
|
-
const removed = gate.unregisterExtension('e2e');
|
|
83
|
-
expect(removed).toBe(true);
|
|
84
|
-
expect(gate.getExtensionNames()).not.toContain('e2e');
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('unregisterExtension returns false for non-existent extension', () => {
|
|
88
|
-
const gate = createPassesGate();
|
|
89
|
-
const removed = gate.unregisterExtension('nonexistent');
|
|
90
|
-
expect(removed).toBe(false);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('getExtensionNames returns empty array when no extensions', () => {
|
|
94
|
-
const gate = createPassesGate();
|
|
95
|
-
expect(gate.getExtensionNames()).toEqual([]);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('getExtensionNames returns multiple extension names', () => {
|
|
99
|
-
const gate = createPassesGate();
|
|
100
|
-
gate.registerExtension('a', { name: 'a', run: async () => ({ passed: true, command: 'a' }) });
|
|
101
|
-
gate.registerExtension('b', { name: 'b', run: async () => ({ passed: true, command: 'b' }) });
|
|
102
|
-
const names = gate.getExtensionNames();
|
|
103
|
-
expect(names).toContain('a');
|
|
104
|
-
expect(names).toContain('b');
|
|
105
|
-
expect(names).toHaveLength(2);
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
|
|
109
71
|
describe('getTestResult', () => {
|
|
110
72
|
it('returns undefined for unknown task', () => {
|
|
111
73
|
const gate = createPassesGate();
|
|
112
74
|
expect(gate.getTestResult('unknown')).toBeUndefined();
|
|
113
75
|
});
|
|
114
76
|
});
|
|
115
|
-
|
|
116
|
-
describe('extractCoverage (via extractCoverage private method behavior check)', () => {
|
|
117
|
-
// extractCoverage is private but we can infer behavior through public API
|
|
118
|
-
// runTest uses it internally — but that method is not easily testable without mocking exec
|
|
119
|
-
it('PassesGate instance is properly constructed', () => {
|
|
120
|
-
const gate = createPassesGate({ testCommand: 'npm test' });
|
|
121
|
-
expect(gate).toBeInstanceOf(PassesGate);
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
describe('extractFailures (via extractFailures private method behavior check)', () => {
|
|
126
|
-
it('PassesGate handles config properly', () => {
|
|
127
|
-
const gate = createPassesGate({ allowPartialPass: true, maxRetries: 0, retryDelay: 0 });
|
|
128
|
-
expect(gate).toBeInstanceOf(PassesGate);
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
77
|
});
|