@dommaker/harness 1.3.0 → 1.5.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 +20 -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 +104 -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 +27 -219
- 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 +17 -30
- package/dist/cli/commands/knowledge.d.ts.map +1 -1
- package/dist/cli/commands/knowledge.js +183 -273
- 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 +9 -3
- package/dist/cli/commands/update-user-model.d.ts.map +1 -1
- package/dist/cli/commands/update-user-model.js +56 -61
- 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 +68 -117
- package/dist/core/constraints/checker.js.map +1 -1
- package/dist/core/constraints/checkers/capability-sync.d.ts +20 -8
- package/dist/core/constraints/checkers/capability-sync.d.ts.map +1 -1
- package/dist/core/constraints/checkers/capability-sync.js +66 -77
- 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 +49 -66
- 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/index.d.ts +2 -2
- package/dist/core/constraints/checkers/index.d.ts.map +1 -1
- package/dist/core/constraints/checkers/index.js +2 -1
- package/dist/core/constraints/checkers/index.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 +43 -4
- package/dist/core/constraints/checkers/types.d.ts.map +1 -1
- package/dist/core/constraints/checkers/types.js +33 -0
- package/dist/core/constraints/checkers/types.js.map +1 -1
- 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 +2 -1
- package/dist/gates/checker-gate.d.ts.map +1 -1
- package/dist/gates/checker-gate.js +11 -13
- 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 +8 -18
- package/dist/types/constraint.d.ts.map +1 -1
- package/dist/types/constraint.js +6 -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/types/trace.d.ts +9 -0
- package/dist/types/trace.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 +8 -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 +130 -101
- 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 +23 -8
- 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 +107 -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 +448 -378
- 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 +231 -0
- package/src/cli/commands/__tests__/registry.test.ts +75 -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 +97 -34
- 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 +127 -66
- 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 +34 -227
- package/src/cli/commands/failure.ts +33 -26
- package/src/cli/commands/init.ts +166 -220
- package/src/cli/commands/knowledge.ts +192 -289
- 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 +64 -61
- 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 +10 -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 +82 -133
- package/src/core/constraints/checkers/__tests__/capability-sync.test.ts +273 -0
- package/src/core/constraints/checkers/__tests__/check-outcome.test.ts +176 -0
- package/src/core/constraints/checkers/__tests__/context-doc-sync.test.ts +77 -0
- package/src/core/constraints/checkers/__tests__/docs-freshness.test.ts +126 -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 +153 -0
- package/src/core/constraints/checkers/capability-sync.ts +75 -96
- package/src/core/constraints/checkers/context-doc-sync.ts +15 -25
- package/src/core/constraints/checkers/docs-freshness.ts +54 -70
- package/src/core/constraints/checkers/governance-presence.ts +7 -25
- package/src/core/constraints/checkers/index.ts +9 -2
- package/src/core/constraints/checkers/no-test-simplification.ts +4 -3
- package/src/core/constraints/checkers/types.ts +60 -4
- 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 +7 -4
- 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__/checker-gate.test.ts +24 -0
- 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 +12 -15
- 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 +16 -27
- 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/types/trace.ts +10 -0
- 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
|
@@ -4,18 +4,51 @@
|
|
|
4
4
|
* 检查约束是否满足(check 层:Iron Laws / Guidelines;prompt 层仅注入不检查)
|
|
5
5
|
* 工单 23:触发条件与证据检测迁至 core/constraints/context-builder
|
|
6
6
|
* ADR-0001:约束集统一走 getMergedConstraintsConfig 生效集链路(preset/config 禁用/custom/scenes)
|
|
7
|
+
* harness#88:本命令是 trace 记录器的组合根——core 不上行依赖 monitoring,
|
|
8
|
+
* 真实收集器在此经构造参数接线
|
|
7
9
|
*/
|
|
8
10
|
|
|
9
11
|
import chalk from 'chalk';
|
|
10
12
|
import * as fs from 'fs';
|
|
11
13
|
import * as path from 'path';
|
|
12
|
-
import {
|
|
14
|
+
import { ConstraintChecker } from '../../core/constraints/checker';
|
|
13
15
|
import { IRON_LAWS, GUIDELINES, PROMPTS } from '../../core/constraints/definitions';
|
|
14
16
|
import { getMergedConstraintsConfig } from '../../core/effective-constraints';
|
|
15
17
|
import { buildConstraintContext } from '../../core/constraints/context-builder';
|
|
18
|
+
import { createGitEvidence, type GitEvidence } from '../../core/constraints/git-evidence';
|
|
16
19
|
import { detectInjectionDrift } from '../../core/constraints/injection-drift';
|
|
20
|
+
import { GOVERNANCE_HEADING } from '../../core/constraints/injection-writer';
|
|
21
|
+
import { getTraceCollector } from '../../monitoring/traces';
|
|
22
|
+
import { countJsonlLines } from '../../utils/jsonl';
|
|
17
23
|
import { DEFAULT_TRACE_FILE } from '../../types/trace';
|
|
18
|
-
import type { ConstraintTrigger } from '../../types/constraint';
|
|
24
|
+
import type { ConstraintResult, ConstraintTrigger } from '../../types/constraint';
|
|
25
|
+
import { log, processIO, type CommandIO, type CommandResult } from '../command-contract';
|
|
26
|
+
|
|
27
|
+
/** 证据行着色(与调用处所属结论块一致) */
|
|
28
|
+
const EVIDENCE_PAINT = {
|
|
29
|
+
red: chalk.red,
|
|
30
|
+
yellow: chalk.yellow,
|
|
31
|
+
gray: chalk.gray,
|
|
32
|
+
} as const;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 打印 checker 的判定证据行(harness#119)
|
|
36
|
+
*
|
|
37
|
+
* 文案由 checker 自行措辞(每行自描述),CLI 只负责缩进与着色——
|
|
38
|
+
* 不在这里解释内容,否则证据形状与措辞会两头漂移。
|
|
39
|
+
* 传 id 时首行挂上约束 id(提示块里没有父级结论行可依附)。
|
|
40
|
+
*/
|
|
41
|
+
function logEvidence(
|
|
42
|
+
io: CommandIO,
|
|
43
|
+
result: ConstraintResult,
|
|
44
|
+
color: keyof typeof EVIDENCE_PAINT,
|
|
45
|
+
id?: string
|
|
46
|
+
): void {
|
|
47
|
+
const paint = EVIDENCE_PAINT[color];
|
|
48
|
+
(result.evidence ?? []).forEach((line, index) => {
|
|
49
|
+
log(io, paint(index === 0 && id ? ` - ${id}: ${line}` : ` ${line}`));
|
|
50
|
+
});
|
|
51
|
+
}
|
|
19
52
|
|
|
20
53
|
export interface CheckOptions {
|
|
21
54
|
/** 预设名称 */
|
|
@@ -26,14 +59,24 @@ export interface CheckOptions {
|
|
|
26
59
|
trigger?: ConstraintTrigger;
|
|
27
60
|
/** 项目路径 */
|
|
28
61
|
projectPath?: string;
|
|
62
|
+
/**
|
|
63
|
+
* git 证据 adapter(非 CLI flag;#87)
|
|
64
|
+
*
|
|
65
|
+
* 缺省 = 本 run 独占一份真 git 证据。注入则与调用方共用同一证据快照,
|
|
66
|
+
* 测试据此断言"同一 run 内每条 git 命令至多执行一次"。
|
|
67
|
+
*/
|
|
68
|
+
evidence?: GitEvidence;
|
|
29
69
|
}
|
|
30
70
|
|
|
31
71
|
/**
|
|
32
72
|
* 执行约束检查
|
|
33
73
|
*/
|
|
34
|
-
export async function check(
|
|
35
|
-
|
|
36
|
-
|
|
74
|
+
export async function check(
|
|
75
|
+
options: CheckOptions,
|
|
76
|
+
io: CommandIO = processIO,
|
|
77
|
+
): Promise<CommandResult> {
|
|
78
|
+
log(io, chalk.blue('🔍 检查约束...'));
|
|
79
|
+
log(io, chalk.gray(`预设: ${options.preset}`));
|
|
37
80
|
|
|
38
81
|
try {
|
|
39
82
|
const projectPath = options.projectPath || process.cwd();
|
|
@@ -43,33 +86,38 @@ export async function check(options: CheckOptions): Promise<void> {
|
|
|
43
86
|
// 项目自定义配置优先于 CLI 预设),优先级规则收在 getMergedConstraintsConfig 一处。
|
|
44
87
|
const merged = getMergedConstraintsConfig(projectPath, { preset: options.preset });
|
|
45
88
|
if (merged.custom.length > 0) {
|
|
46
|
-
|
|
89
|
+
log(io, chalk.gray(`自定义约束: ${merged.custom.length} 条`));
|
|
47
90
|
}
|
|
48
91
|
if (merged.disabled.length > 0) {
|
|
49
|
-
|
|
92
|
+
log(io, chalk.gray(`已禁用约束: ${merged.disabled.join(', ')}`));
|
|
50
93
|
}
|
|
51
94
|
const unknownIds = merged.unknownIds ?? [];
|
|
52
95
|
if (unknownIds.length > 0) {
|
|
53
|
-
|
|
96
|
+
log(io, chalk.yellow(`⚠️ 配置中存在未知约束 id(已忽略,可清理): ${unknownIds.join(', ')}`));
|
|
54
97
|
}
|
|
55
98
|
|
|
56
99
|
// 构建上下文(工单 23:触发条件与证据检测收敛至 core/constraints/context-builder)
|
|
100
|
+
// #87:一次 run 一份 git 证据——context-builder 与 checker 层共用同一实例
|
|
101
|
+
const evidence = options.evidence ?? createGitEvidence(projectPath);
|
|
57
102
|
const context = await buildConstraintContext({
|
|
58
103
|
projectPath: options.projectPath,
|
|
59
104
|
staged: options.staged,
|
|
60
105
|
trigger: options.trigger,
|
|
106
|
+
evidence,
|
|
61
107
|
});
|
|
62
108
|
const changedFiles = context.changedFiles ?? [];
|
|
63
109
|
if (changedFiles.length > 0) {
|
|
64
|
-
|
|
110
|
+
log(io, chalk.gray(`变更文件: ${changedFiles.length} 个`));
|
|
65
111
|
}
|
|
66
|
-
|
|
112
|
+
log(io, chalk.gray(`触发条件: ${[context.operation, ...(context.extraTriggers ?? [])].join(', ')}`));
|
|
67
113
|
|
|
68
|
-
// 执行三层检查(per-request 传 customConfig
|
|
69
|
-
|
|
114
|
+
// 执行三层检查(per-request 传 customConfig,避免单例状态污染;证据同 run 同源)
|
|
115
|
+
// trace 记录器经构造参数接线(harness#88):一次命令一个 checker 实例
|
|
116
|
+
const checker = new ConstraintChecker(getTraceCollector());
|
|
117
|
+
const result = await checker.checkConstraints(context, merged, evidence);
|
|
70
118
|
|
|
71
119
|
// 输出结果
|
|
72
|
-
|
|
120
|
+
log(io);
|
|
73
121
|
|
|
74
122
|
// skipped(约定未采用/证据未接线)单独列示,不进 pass/fail 统计(ADR-0001)
|
|
75
123
|
const skippedResults = [
|
|
@@ -81,39 +129,54 @@ export async function check(options: CheckOptions): Promise<void> {
|
|
|
81
129
|
const evaluatedIronLaws = result.ironLaws.filter(r => !r.skipped);
|
|
82
130
|
const ironLawViolations = evaluatedIronLaws.filter(r => !r.satisfied);
|
|
83
131
|
if (ironLawViolations.length === 0 && evaluatedIronLaws.length > 0) {
|
|
84
|
-
|
|
132
|
+
log(io, chalk.green(`✅ 铁律: 全部通过 (${evaluatedIronLaws.length} 条)`));
|
|
85
133
|
} else if (ironLawViolations.length > 0) {
|
|
86
|
-
|
|
134
|
+
log(io, chalk.red(`❌ 铁律违规: ${ironLawViolations.length} 条`));
|
|
87
135
|
ironLawViolations.forEach(r => {
|
|
88
136
|
if (r.constraint) {
|
|
89
|
-
|
|
90
|
-
|
|
137
|
+
log(io, chalk.red(` - ${r.constraint.id}: ${r.constraint.message}`));
|
|
138
|
+
log(io, chalk.red(` ${r.constraint.rule}`));
|
|
139
|
+
logEvidence(io, r, 'red');
|
|
91
140
|
}
|
|
92
141
|
});
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
142
|
+
log(io);
|
|
143
|
+
log(io, chalk.red('🛑 铁律检查失败,请修复后再提交'));
|
|
144
|
+
return {
|
|
145
|
+
kind: 'fail',
|
|
146
|
+
reason: `iron law violated: ${ironLawViolations.map(r => r.constraint?.id ?? 'unknown').join(', ')}`,
|
|
147
|
+
};
|
|
96
148
|
}
|
|
97
149
|
|
|
98
150
|
// Guidelines
|
|
99
151
|
if (result.warningCount > 0) {
|
|
100
|
-
|
|
152
|
+
log(io, chalk.yellow(`⚠️ 指导原则警告: ${result.warningCount} 条`));
|
|
101
153
|
result.guidelines.filter(r => !r.satisfied).forEach(r => {
|
|
102
154
|
if (r.constraint) {
|
|
103
|
-
|
|
155
|
+
log(io, chalk.yellow(` - ${r.constraint.id}: ${r.constraint.message}`));
|
|
156
|
+
logEvidence(io, r, 'yellow');
|
|
104
157
|
}
|
|
105
158
|
});
|
|
106
159
|
} else if (result.guidelines.length > 0) {
|
|
107
160
|
const evaluatedGuidelines = result.guidelines.filter(r => !r.skipped);
|
|
108
161
|
const passedGuidelines = evaluatedGuidelines.filter(r => r.satisfied).length;
|
|
109
|
-
|
|
162
|
+
log(io, chalk.green(`✅ 指导原则: ${passedGuidelines}/${evaluatedGuidelines.length} 通过`));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 提示:通过但带证据(harness#119)——与本次变更无因果的仓库级漂移在此露出,
|
|
166
|
+
// 不判违规、不改 exit code,只保证「看得见且能自己修」
|
|
167
|
+
const hints = [...result.ironLaws, ...result.guidelines].filter(
|
|
168
|
+
r => !r.skipped && r.satisfied && (r.evidence?.length ?? 0) > 0
|
|
169
|
+
);
|
|
170
|
+
if (hints.length > 0) {
|
|
171
|
+
log(io, chalk.gray(`💡 提示: ${hints.length} 条(不判违规,供参考)`));
|
|
172
|
+
hints.forEach(r => logEvidence(io, r, 'gray', r.id));
|
|
110
173
|
}
|
|
111
174
|
|
|
112
175
|
// Skipped:约定未采用 / 证据未接线,未评估(不计通过/失败)
|
|
113
176
|
if (skippedResults.length > 0) {
|
|
114
|
-
|
|
177
|
+
log(io, chalk.gray(`⏭️ 跳过评估: ${skippedResults.length} 条(约定未采用或证据未接线,不计通过/失败)`));
|
|
115
178
|
skippedResults.forEach(r => {
|
|
116
|
-
|
|
179
|
+
log(io, chalk.gray(` - ${r.id}`));
|
|
117
180
|
});
|
|
118
181
|
}
|
|
119
182
|
|
|
@@ -122,38 +185,39 @@ export async function check(options: CheckOptions): Promise<void> {
|
|
|
122
185
|
try {
|
|
123
186
|
const drift = detectInjectionDrift(projectPath);
|
|
124
187
|
if (drift.hasDrift) {
|
|
125
|
-
|
|
126
|
-
|
|
188
|
+
log(io);
|
|
189
|
+
log(io, chalk.yellow(`⚠️ 检测到 ${drift.injectionFile ?? '治理文档'} 约束注入漂移(仅警告,不阻断):`));
|
|
127
190
|
if (drift.versionDrift) {
|
|
128
|
-
|
|
191
|
+
log(io, chalk.yellow(` ⚠️⚠️ 注入段版本 (${drift.versionDrift.actual}) ≠ 已安装 harness 版本 (${drift.versionDrift.expected}):agent 上下文中的规则与已安装 harness 版本不一致`));
|
|
129
192
|
}
|
|
130
193
|
if (drift.contentDrift) {
|
|
131
|
-
|
|
194
|
+
log(io, chalk.yellow(` 内容漂移: 缺失 ${drift.contentDrift.missing.length} 条 / 多余 ${drift.contentDrift.extra.length} 条(条目级差异见 harness constraints report)`));
|
|
132
195
|
}
|
|
133
196
|
if (drift.duplicateHeading) {
|
|
134
|
-
|
|
197
|
+
log(io, chalk.yellow(` 检测到重复的 "${GOVERNANCE_HEADING}" 章节`));
|
|
135
198
|
}
|
|
136
|
-
|
|
199
|
+
log(io, chalk.yellow(` 修复: ${drift.fixHint}`));
|
|
137
200
|
}
|
|
138
201
|
} catch {
|
|
139
202
|
// 漂移检测失败不影响 check 结果
|
|
140
203
|
}
|
|
141
204
|
|
|
142
|
-
|
|
143
|
-
|
|
205
|
+
log(io);
|
|
206
|
+
log(io, chalk.green('✅ 约束检查通过'));
|
|
144
207
|
|
|
145
208
|
// 智能提示
|
|
146
209
|
const hint = await getSmartHint(projectPath);
|
|
147
210
|
if (hint) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
211
|
+
log(io);
|
|
212
|
+
log(io, chalk.gray('────────────────────────────────────'));
|
|
213
|
+
log(io, hint);
|
|
214
|
+
log(io, chalk.gray('────────────────────────────────────'));
|
|
152
215
|
}
|
|
216
|
+
return { kind: 'ok' };
|
|
153
217
|
} catch (error) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
218
|
+
log(io);
|
|
219
|
+
log(io, chalk.red(`❌ 约束检查异常: ${error instanceof Error ? error.message : String(error)}`));
|
|
220
|
+
return { kind: 'fail', reason: `check error: ${error instanceof Error ? error.message : String(error)}` };
|
|
157
221
|
}
|
|
158
222
|
}
|
|
159
223
|
|
|
@@ -163,17 +227,12 @@ export async function check(options: CheckOptions): Promise<void> {
|
|
|
163
227
|
async function getSmartHint(projectPath: string): Promise<string | null> {
|
|
164
228
|
const tracesPath = path.join(projectPath, DEFAULT_TRACE_FILE);
|
|
165
229
|
const statePath = path.join(projectPath, '.harness', '.state.json');
|
|
166
|
-
|
|
167
|
-
//
|
|
168
|
-
|
|
230
|
+
|
|
231
|
+
// 只数非空行数(含坏行),零 parse——原语义不变,走 jsonl 正本(harness#82)
|
|
232
|
+
const traceCount = countJsonlLines(tracesPath);
|
|
233
|
+
if (traceCount === 0) {
|
|
169
234
|
return null;
|
|
170
235
|
}
|
|
171
|
-
|
|
172
|
-
// 读取 trace 记录数
|
|
173
|
-
const tracesContent = fs.readFileSync(tracesPath, 'utf-8');
|
|
174
|
-
const lines = tracesContent.trim().split('\n').filter(Boolean);
|
|
175
|
-
const traceCount = lines.length;
|
|
176
|
-
|
|
177
236
|
// 读取状态
|
|
178
237
|
let state: {
|
|
179
238
|
shownHints?: string[];
|
|
@@ -206,33 +265,35 @@ async function getSmartHint(projectPath: string): Promise<string | null> {
|
|
|
206
265
|
/**
|
|
207
266
|
* 列出所有约束
|
|
208
267
|
*/
|
|
209
|
-
|
|
210
|
-
|
|
268
|
+
/** optionRoutes 一律以 (options) 调用;--list 不消费检查选项,形参仅占位 */
|
|
269
|
+
export function listLaws(_options: Partial<CheckOptions> = {}, io: CommandIO = processIO): CommandResult {
|
|
270
|
+
log(io, chalk.blue('\n📜 所有约束:\n'));
|
|
211
271
|
|
|
212
272
|
// Iron Laws
|
|
213
|
-
|
|
273
|
+
log(io, chalk.red('🔴 铁律 (Iron Laws) - 绝对禁止,无例外:\n'));
|
|
214
274
|
Object.values(IRON_LAWS).forEach(constraint => {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
275
|
+
log(io, chalk.red(` ${constraint.id}`));
|
|
276
|
+
log(io, chalk.gray(` ${constraint.rule}`));
|
|
277
|
+
log(io, chalk.gray(` ${constraint.message}`));
|
|
278
|
+
log(io);
|
|
219
279
|
});
|
|
220
280
|
|
|
221
281
|
// Guidelines
|
|
222
|
-
|
|
282
|
+
log(io, chalk.yellow('🟡 指导原则 (Guidelines) - 优先建议,违背发警告但不阻止:\n'));
|
|
223
283
|
Object.values(GUIDELINES).forEach(constraint => {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
284
|
+
log(io, chalk.yellow(` ${constraint.id}`));
|
|
285
|
+
log(io, chalk.gray(` ${constraint.rule}`));
|
|
286
|
+
log(io, chalk.gray(` ${constraint.message}`));
|
|
287
|
+
log(io);
|
|
228
288
|
});
|
|
229
289
|
|
|
230
290
|
// Prompts(ADR-0001:纯注入层,不执行检查)
|
|
231
|
-
|
|
291
|
+
log(io, chalk.blue('🔵 提示 (Prompts) - 纯文本注入,不参与检查:\n'));
|
|
232
292
|
Object.values(PROMPTS).forEach(constraint => {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
293
|
+
log(io, chalk.blue(` ${constraint.id}`));
|
|
294
|
+
log(io, chalk.gray(` ${constraint.rule}`));
|
|
295
|
+
log(io, chalk.gray(` ${constraint.message}`));
|
|
296
|
+
log(io);
|
|
237
297
|
});
|
|
298
|
+
return { kind: 'ok' };
|
|
238
299
|
}
|
|
@@ -5,9 +5,13 @@
|
|
|
5
5
|
* harness command "rm -rf /"
|
|
6
6
|
* harness command --level "DROP TABLE users"
|
|
7
7
|
* harness command --list
|
|
8
|
+
*
|
|
9
|
+
* 判定经返回值外溢(架构评审候选7):风险等级/黑名单裁决译成 kind,
|
|
10
|
+
* 退出码映射收敛在 bin 一处。
|
|
8
11
|
*/
|
|
9
12
|
|
|
10
13
|
import { createCommandGate, getCommandRiskLevel, DEFAULT_COMMAND_BLACKLIST, type CommandBlacklistRule } from '../../gates';
|
|
14
|
+
import { log, logError, processIO, type CommandIO, type CommandResult } from '../command-contract';
|
|
11
15
|
|
|
12
16
|
export interface CommandCheckOptions {
|
|
13
17
|
level?: boolean;
|
|
@@ -19,17 +23,21 @@ export interface CommandCheckOptions {
|
|
|
19
23
|
/**
|
|
20
24
|
* 执行命令黑名单检查(供 bin/harness.js 调用)
|
|
21
25
|
*/
|
|
22
|
-
export async function executeCommand(
|
|
26
|
+
export async function executeCommand(
|
|
27
|
+
cmd: string | undefined,
|
|
28
|
+
options: CommandCheckOptions,
|
|
29
|
+
io: CommandIO = processIO,
|
|
30
|
+
): Promise<CommandResult> {
|
|
23
31
|
if (options.list) {
|
|
24
32
|
if (options.json) {
|
|
25
|
-
|
|
33
|
+
log(io, JSON.stringify(DEFAULT_COMMAND_BLACKLIST.map((r: CommandBlacklistRule) => ({
|
|
26
34
|
id: r.id,
|
|
27
35
|
level: r.level,
|
|
28
36
|
message: r.message,
|
|
29
37
|
category: r.category,
|
|
30
38
|
})), null, 2));
|
|
31
39
|
} else {
|
|
32
|
-
|
|
40
|
+
log(io, '\n命令黑名单规则:\n');
|
|
33
41
|
|
|
34
42
|
const byCategory = DEFAULT_COMMAND_BLACKLIST.reduce((acc: Record<string, CommandBlacklistRule[]>, rule: CommandBlacklistRule) => {
|
|
35
43
|
if (!acc[rule.category]) acc[rule.category] = [];
|
|
@@ -38,23 +46,23 @@ export async function executeCommand(cmd: string | undefined, options: CommandCh
|
|
|
38
46
|
}, {});
|
|
39
47
|
|
|
40
48
|
for (const [category, rules] of Object.entries(byCategory)) {
|
|
41
|
-
|
|
49
|
+
log(io, `[${category}]`);
|
|
42
50
|
for (const rule of rules as CommandBlacklistRule[]) {
|
|
43
51
|
const levelIcon = rule.level === 'block' ? '🚫' : rule.level === 'warn' ? '⚠️' : '📋';
|
|
44
|
-
|
|
52
|
+
log(io, ` ${levelIcon} ${rule.id}: ${rule.message} (${rule.level})`);
|
|
45
53
|
}
|
|
46
|
-
|
|
54
|
+
log(io);
|
|
47
55
|
}
|
|
48
56
|
|
|
49
|
-
|
|
57
|
+
log(io, `共 ${DEFAULT_COMMAND_BLACKLIST.length} 条规则`);
|
|
50
58
|
}
|
|
51
|
-
return;
|
|
59
|
+
return { kind: 'ok' };
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
if (!cmd) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
logError(io, '错误:请提供要检查的命令');
|
|
64
|
+
logError(io, '用法:harness command "your command"');
|
|
65
|
+
return { kind: 'usage-error', reason: '缺少要检查的命令参数' };
|
|
58
66
|
}
|
|
59
67
|
|
|
60
68
|
const gate = createCommandGate({ strict: options.strict });
|
|
@@ -63,28 +71,33 @@ export async function executeCommand(cmd: string | undefined, options: CommandCh
|
|
|
63
71
|
if (options.level) {
|
|
64
72
|
const level = getCommandRiskLevel(cmd);
|
|
65
73
|
if (options.json) {
|
|
66
|
-
|
|
74
|
+
log(io, JSON.stringify({ level, command: cmd }));
|
|
67
75
|
} else {
|
|
68
76
|
const levelColors: Record<string, string> = {
|
|
69
77
|
high: '\x1b[31m',
|
|
70
78
|
medium: '\x1b[33m',
|
|
71
79
|
low: '\x1b[32m',
|
|
72
80
|
};
|
|
73
|
-
|
|
81
|
+
log(io, `${levelColors[level]}${level}\x1b[0m ${cmd}`);
|
|
74
82
|
}
|
|
75
|
-
|
|
83
|
+
// 严重级闸门(历史条件式):high → 非零退出
|
|
84
|
+
return level === 'high'
|
|
85
|
+
? { kind: 'fail', reason: `command risk level is high: ${cmd}` }
|
|
86
|
+
: { kind: 'ok' };
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
if (options.json) {
|
|
79
|
-
|
|
90
|
+
log(io, JSON.stringify({
|
|
80
91
|
command: cmd,
|
|
81
92
|
passed: result.passed,
|
|
82
93
|
message: result.message,
|
|
83
94
|
details: result.details,
|
|
84
95
|
}, null, 2));
|
|
85
96
|
} else {
|
|
86
|
-
|
|
97
|
+
log(io, result.passed ? `\x1b[32m✓\x1b[0m ${result.message}` : `\x1b[31m✗\x1b[0m ${result.message}`);
|
|
87
98
|
}
|
|
88
99
|
|
|
89
|
-
|
|
100
|
+
return result.passed
|
|
101
|
+
? { kind: 'ok' }
|
|
102
|
+
: { kind: 'fail', reason: `command gate denied: ${result.message}` };
|
|
90
103
|
}
|
|
@@ -14,14 +14,16 @@ import * as path from 'path';
|
|
|
14
14
|
import chalk from 'chalk';
|
|
15
15
|
import {
|
|
16
16
|
buildConstraintsUsageReport,
|
|
17
|
+
CANDIDATE_KIND_LABEL,
|
|
17
18
|
DEFAULT_DIAGNOSE_THRESHOLDS,
|
|
18
19
|
type ConstraintsUsageReport,
|
|
19
20
|
type ConstraintUsageStats,
|
|
20
21
|
type DiagnoseThresholds,
|
|
21
|
-
type RetireCandidate,
|
|
22
22
|
} from '../../core/constraints/usage-report';
|
|
23
23
|
import { getConstraintsMeta } from './constraints';
|
|
24
24
|
import { detectInjectionDrift, type InjectionDrift } from '../../core/constraints/injection-drift';
|
|
25
|
+
import { GOVERNANCE_HEADING } from '../../core/constraints/injection-writer';
|
|
26
|
+
import { log, processIO, type CommandIO, type CommandResult } from '../command-contract';
|
|
25
27
|
|
|
26
28
|
export interface ConstraintsReportOptions {
|
|
27
29
|
projectPath?: string;
|
|
@@ -36,13 +38,6 @@ export interface ConstraintsReportOptions {
|
|
|
36
38
|
noiseMinTotal?: number;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
const CANDIDATE_KIND_LABEL: Record<RetireCandidate['kind'], string> = {
|
|
40
|
-
zero_trigger: '零触发',
|
|
41
|
-
unevaluable: '不可评估',
|
|
42
|
-
high_noise: '高噪',
|
|
43
|
-
zero_intercept: '零拦截',
|
|
44
|
-
};
|
|
45
|
-
|
|
46
41
|
function formatTime(ts: number | undefined): string {
|
|
47
42
|
return ts === undefined ? '-' : new Date(ts).toISOString().slice(0, 10);
|
|
48
43
|
}
|
|
@@ -74,6 +69,10 @@ export function renderExportMarkdown(
|
|
|
74
69
|
lines.push('');
|
|
75
70
|
lines.push(`- harness 版本: ${version}`);
|
|
76
71
|
lines.push(`- 日期: ${now.toISOString().slice(0, 10)}`);
|
|
72
|
+
if (report.skippedLines > 0) {
|
|
73
|
+
// 脱敏:只报条数,不报路径、不报坏行内容
|
|
74
|
+
lines.push(`- ⚠️ trace 文件有 ${report.skippedLines} 行损坏已跳过,下表统计只含其余合法记录`);
|
|
75
|
+
}
|
|
77
76
|
lines.push('');
|
|
78
77
|
|
|
79
78
|
lines.push('## 统计表(check 层)');
|
|
@@ -120,7 +119,7 @@ export function renderInjectionDriftLines(drift: InjectionDrift): string[] {
|
|
|
120
119
|
if (drift.notInjected) {
|
|
121
120
|
lines.push(' CLAUDE.md / AGENTS.md 均无约束注入标记段(未注入,不算漂移);可运行 npx @dommaker/harness init 注入');
|
|
122
121
|
if (drift.duplicateHeading) {
|
|
123
|
-
lines.push(
|
|
122
|
+
lines.push(` 另检测到多个 "${GOVERNANCE_HEADING}" 标题(历史遗留重复章节),建议手工清理后重跑 npx @dommaker/harness init`);
|
|
124
123
|
}
|
|
125
124
|
return lines;
|
|
126
125
|
}
|
|
@@ -141,7 +140,7 @@ export function renderInjectionDriftLines(drift: InjectionDrift): string[] {
|
|
|
141
140
|
}
|
|
142
141
|
}
|
|
143
142
|
if (drift.duplicateHeading) {
|
|
144
|
-
lines.push(
|
|
143
|
+
lines.push(` 重复章节: 标记段之外还存在另一个 "${GOVERNANCE_HEADING}" 标题`);
|
|
145
144
|
}
|
|
146
145
|
lines.push(` 修复: ${drift.fixHint}`);
|
|
147
146
|
return lines;
|
|
@@ -150,7 +149,7 @@ export function renderInjectionDriftLines(drift: InjectionDrift): string[] {
|
|
|
150
149
|
/**
|
|
151
150
|
* CLI handler: harness constraints report
|
|
152
151
|
*/
|
|
153
|
-
export async function constraintsReport(options: ConstraintsReportOptions = {}): Promise<
|
|
152
|
+
export async function constraintsReport(options: ConstraintsReportOptions = {}, io: CommandIO = processIO): Promise<CommandResult> {
|
|
154
153
|
const projectRoot = options.projectPath || process.cwd();
|
|
155
154
|
const thresholds: Partial<DiagnoseThresholds> = {};
|
|
156
155
|
if (options.zeroInterceptMin !== undefined) thresholds.zeroInterceptMinEvaluated = options.zeroInterceptMin;
|
|
@@ -160,58 +159,61 @@ export async function constraintsReport(options: ConstraintsReportOptions = {}):
|
|
|
160
159
|
const report = buildConstraintsUsageReport(projectRoot, thresholds);
|
|
161
160
|
|
|
162
161
|
if (options.json) {
|
|
163
|
-
|
|
164
|
-
return;
|
|
162
|
+
log(io, JSON.stringify(report, null, 2));
|
|
163
|
+
return { kind: 'ok' };
|
|
165
164
|
}
|
|
166
165
|
|
|
167
|
-
|
|
166
|
+
log(io, chalk.blue('📊 约束使用报告'));
|
|
168
167
|
if (!report.traceFileExists) {
|
|
169
|
-
|
|
168
|
+
log(io, chalk.gray(' (trace 文件不存在,全部按零触发统计)'));
|
|
169
|
+
}
|
|
170
|
+
if (report.skippedLines > 0) {
|
|
171
|
+
log(io, chalk.yellow(` ⚠️ trace 文件有 ${report.skippedLines} 行损坏已跳过,统计只含其余合法记录(数据不完整)`));
|
|
170
172
|
}
|
|
171
|
-
|
|
173
|
+
log(io);
|
|
172
174
|
|
|
173
175
|
// 统计表
|
|
174
|
-
|
|
176
|
+
log(io, chalk.bold('统计表(check 层):'));
|
|
175
177
|
for (const s of report.stats) {
|
|
176
|
-
|
|
178
|
+
log(io, ` ${renderStatsRow(s)}`);
|
|
177
179
|
}
|
|
178
|
-
|
|
180
|
+
log(io);
|
|
179
181
|
|
|
180
182
|
// 候选诊断
|
|
181
|
-
|
|
183
|
+
log(io, chalk.bold(`退役候选(${report.candidates.length} 条,阈值: 零拦截≥${thresholds.zeroInterceptMinEvaluated ?? DEFAULT_DIAGNOSE_THRESHOLDS.zeroInterceptMinEvaluated} 次评估, 高噪 fail率>${Math.round((thresholds.highNoiseFailRate ?? DEFAULT_DIAGNOSE_THRESHOLDS.highNoiseFailRate) * 100)}% 且 ≥${thresholds.highNoiseMinEvaluated ?? DEFAULT_DIAGNOSE_THRESHOLDS.highNoiseMinEvaluated} 次评估):`));
|
|
182
184
|
if (report.candidates.length === 0) {
|
|
183
|
-
|
|
185
|
+
log(io, chalk.green(' (无候选)'));
|
|
184
186
|
} else {
|
|
185
187
|
for (const c of report.candidates) {
|
|
186
|
-
|
|
188
|
+
log(io, ` [${CANDIDATE_KIND_LABEL[c.kind]}] ${c.id} — ${c.reason}`);
|
|
187
189
|
}
|
|
188
|
-
|
|
190
|
+
log(io, chalk.gray(' 可运行 `harness constraints retire` 交互式处理候选'));
|
|
189
191
|
}
|
|
190
|
-
|
|
192
|
+
log(io);
|
|
191
193
|
|
|
192
194
|
// 注入清单
|
|
193
|
-
|
|
195
|
+
log(io, chalk.bold(`当前生效 prompt 注入(${report.activePromptIds.length} 条):`));
|
|
194
196
|
for (const id of report.activePromptIds) {
|
|
195
|
-
|
|
197
|
+
log(io, ` ${id}`);
|
|
196
198
|
}
|
|
197
|
-
|
|
199
|
+
log(io);
|
|
198
200
|
|
|
199
201
|
// 配置健康
|
|
200
202
|
if (report.lint.unknownIds.length > 0) {
|
|
201
|
-
|
|
203
|
+
log(io, chalk.yellow('⚠️ 配置健康:'));
|
|
202
204
|
for (const id of report.lint.unknownIds) {
|
|
203
|
-
|
|
205
|
+
log(io, chalk.yellow(` config.yml 中禁用了不存在/已移除的约束 id: ${id}(残留配置,建议清理)`));
|
|
204
206
|
}
|
|
205
|
-
|
|
207
|
+
log(io);
|
|
206
208
|
}
|
|
207
209
|
|
|
208
210
|
// 注入漂移(ADR-0001 决策 7:条目级差异 + 修复指引;--export 摘要不含本地漂移状态)
|
|
209
|
-
|
|
211
|
+
log(io, chalk.bold('注入漂移:'));
|
|
210
212
|
const drift = detectInjectionDrift(projectRoot);
|
|
211
213
|
for (const line of renderInjectionDriftLines(drift)) {
|
|
212
|
-
|
|
214
|
+
log(io, drift.hasDrift ? chalk.yellow(line) : line);
|
|
213
215
|
}
|
|
214
|
-
|
|
216
|
+
log(io);
|
|
215
217
|
|
|
216
218
|
// --export
|
|
217
219
|
if (options.export !== undefined && options.export !== false) {
|
|
@@ -229,6 +231,7 @@ export async function constraintsReport(options: ConstraintsReportOptions = {}):
|
|
|
229
231
|
|
|
230
232
|
fs.mkdirSync(path.dirname(exportPath), { recursive: true });
|
|
231
233
|
fs.writeFileSync(exportPath, markdown, 'utf-8');
|
|
232
|
-
|
|
234
|
+
log(io, chalk.green(`✅ 脱敏报告已导出: ${exportPath}`));
|
|
233
235
|
}
|
|
236
|
+
return { kind: 'ok' };
|
|
234
237
|
}
|