@dommaker/harness 1.6.0 → 1.8.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 +52 -0
- package/bin/harness.js +17 -1
- package/dist/agents/index.d.ts +6 -2
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +6 -16
- package/dist/agents/index.js.map +1 -1
- package/dist/cli/commands/__tests__/gate-decision.d.ts +18 -0
- package/dist/cli/commands/__tests__/gate-decision.d.ts.map +1 -0
- package/dist/cli/commands/__tests__/gate-decision.js +26 -0
- package/dist/cli/commands/__tests__/gate-decision.js.map +1 -0
- package/dist/cli/commands/acceptance.d.ts.map +1 -1
- package/dist/cli/commands/acceptance.js +17 -28
- package/dist/cli/commands/acceptance.js.map +1 -1
- package/dist/cli/commands/check.d.ts +11 -3
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +26 -11
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/command.d.ts +0 -1
- package/dist/cli/commands/command.d.ts.map +1 -1
- package/dist/cli/commands/command.js +8 -6
- package/dist/cli/commands/command.js.map +1 -1
- package/dist/cli/commands/constraints-retire.d.ts.map +1 -1
- package/dist/cli/commands/constraints-retire.js +36 -57
- package/dist/cli/commands/constraints-retire.js.map +1 -1
- package/dist/cli/commands/contract.d.ts.map +1 -1
- package/dist/cli/commands/contract.js +36 -42
- package/dist/cli/commands/contract.js.map +1 -1
- package/dist/cli/commands/definitions.d.ts +2 -0
- package/dist/cli/commands/definitions.d.ts.map +1 -1
- package/dist/cli/commands/definitions.js +11 -6
- package/dist/cli/commands/definitions.js.map +1 -1
- package/dist/cli/commands/failure.d.ts.map +1 -1
- package/dist/cli/commands/failure.js +16 -2
- package/dist/cli/commands/failure.js.map +1 -1
- package/dist/cli/commands/init.d.ts +14 -8
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +172 -364
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/knowledge-view.d.ts +90 -0
- package/dist/cli/commands/knowledge-view.d.ts.map +1 -0
- package/dist/cli/commands/knowledge-view.js +198 -0
- package/dist/cli/commands/knowledge-view.js.map +1 -0
- package/dist/cli/commands/knowledge.d.ts +137 -52
- package/dist/cli/commands/knowledge.d.ts.map +1 -1
- package/dist/cli/commands/knowledge.js +534 -400
- package/dist/cli/commands/knowledge.js.map +1 -1
- package/dist/cli/commands/passes-gate.d.ts +4 -1
- package/dist/cli/commands/passes-gate.d.ts.map +1 -1
- package/dist/cli/commands/passes-gate.js +11 -2
- package/dist/cli/commands/passes-gate.js.map +1 -1
- package/dist/cli/commands/performance.d.ts.map +1 -1
- package/dist/cli/commands/performance.js +19 -31
- package/dist/cli/commands/performance.js.map +1 -1
- package/dist/cli/commands/report.d.ts.map +1 -1
- package/dist/cli/commands/report.js +2 -1
- package/dist/cli/commands/report.js.map +1 -1
- package/dist/cli/commands/review.d.ts.map +1 -1
- package/dist/cli/commands/review.js +13 -25
- package/dist/cli/commands/review.js.map +1 -1
- package/dist/cli/commands/scaffold-templates.d.ts +73 -0
- package/dist/cli/commands/scaffold-templates.d.ts.map +1 -0
- package/dist/cli/commands/scaffold-templates.js +424 -0
- package/dist/cli/commands/scaffold-templates.js.map +1 -0
- package/dist/cli/commands/scaffold.d.ts +105 -0
- package/dist/cli/commands/scaffold.d.ts.map +1 -0
- package/dist/cli/commands/scaffold.js +263 -0
- package/dist/cli/commands/scaffold.js.map +1 -0
- package/dist/cli/commands/security.d.ts.map +1 -1
- package/dist/cli/commands/security.js +22 -24
- package/dist/cli/commands/security.js.map +1 -1
- package/dist/cli/commands/spec-baseline-check.d.ts +43 -0
- package/dist/cli/commands/spec-baseline-check.d.ts.map +1 -1
- package/dist/cli/commands/spec-baseline-check.js +109 -34
- package/dist/cli/commands/spec-baseline-check.js.map +1 -1
- package/dist/cli/commands/sync-docs/context-syncer.d.ts +21 -2
- package/dist/cli/commands/sync-docs/context-syncer.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/context-syncer.js +112 -28
- package/dist/cli/commands/sync-docs/context-syncer.js.map +1 -1
- package/dist/cli/commands/sync-docs/index.d.ts +1 -1
- package/dist/cli/commands/sync-docs/index.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/index.js +86 -27
- package/dist/cli/commands/sync-docs/index.js.map +1 -1
- package/dist/cli/commands/sync-docs/project-reader.d.ts +24 -1
- package/dist/cli/commands/sync-docs/project-reader.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/project-reader.js +33 -7
- package/dist/cli/commands/sync-docs/project-reader.js.map +1 -1
- package/dist/cli/commands/validate.d.ts +0 -16
- package/dist/cli/commands/validate.d.ts.map +1 -1
- package/dist/cli/commands/validate.js +2 -97
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/gate-command.d.ts +37 -0
- package/dist/cli/gate-command.d.ts.map +1 -0
- package/dist/cli/gate-command.js +64 -0
- package/dist/cli/gate-command.js.map +1 -0
- package/dist/completion-checkers/index.d.ts +1 -1
- package/dist/completion-checkers/index.d.ts.map +1 -1
- package/dist/completion-checkers/index.js +0 -15
- package/dist/completion-checkers/index.js.map +1 -1
- package/dist/context/knowledge-injector.d.ts +4 -2
- package/dist/context/knowledge-injector.d.ts.map +1 -1
- package/dist/context/knowledge-injector.js +13 -6
- package/dist/context/knowledge-injector.js.map +1 -1
- package/dist/core/constraints/agent-prompt-renderer.js +2 -2
- package/dist/core/constraints/agent-prompt-renderer.js.map +1 -1
- package/dist/core/constraints/capabilities-reconcile.d.ts +20 -0
- package/dist/core/constraints/capabilities-reconcile.d.ts.map +1 -1
- package/dist/core/constraints/capabilities-reconcile.js +26 -4
- package/dist/core/constraints/capabilities-reconcile.js.map +1 -1
- package/dist/core/constraints/check-cache.d.ts +1 -1
- package/dist/core/constraints/check-cache.js +1 -1
- package/dist/core/constraints/checker.d.ts +8 -3
- package/dist/core/constraints/checker.d.ts.map +1 -1
- package/dist/core/constraints/checker.js +30 -19
- package/dist/core/constraints/checker.js.map +1 -1
- package/dist/core/constraints/checkers/capability-sync.d.ts +3 -1
- package/dist/core/constraints/checkers/capability-sync.d.ts.map +1 -1
- package/dist/core/constraints/checkers/capability-sync.js +17 -24
- package/dist/core/constraints/checkers/capability-sync.js.map +1 -1
- package/dist/core/constraints/checkers/context-doc-sync.d.ts +1 -1
- package/dist/core/constraints/checkers/context-doc-sync.d.ts.map +1 -1
- package/dist/core/constraints/checkers/context-doc-sync.js +9 -6
- 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 +24 -30
- package/dist/core/constraints/checkers/docs-freshness.js.map +1 -1
- package/dist/core/constraints/checkers/governance-presence.d.ts.map +1 -1
- package/dist/core/constraints/checkers/governance-presence.js +10 -4
- package/dist/core/constraints/checkers/governance-presence.js.map +1 -1
- package/dist/core/constraints/checkers/types.d.ts +10 -6
- package/dist/core/constraints/checkers/types.d.ts.map +1 -1
- package/dist/core/constraints/checkers/types.js +7 -3
- package/dist/core/constraints/checkers/types.js.map +1 -1
- package/dist/core/constraints/context-builder.d.ts +11 -10
- package/dist/core/constraints/context-builder.d.ts.map +1 -1
- package/dist/core/constraints/context-builder.js +31 -27
- package/dist/core/constraints/context-builder.js.map +1 -1
- package/dist/core/constraints/context-reconcile.d.ts +75 -0
- package/dist/core/constraints/context-reconcile.d.ts.map +1 -0
- package/dist/core/constraints/context-reconcile.js +161 -0
- package/dist/core/constraints/context-reconcile.js.map +1 -0
- package/dist/core/constraints/doc-freshness/runner.d.ts +7 -0
- package/dist/core/constraints/doc-freshness/runner.d.ts.map +1 -1
- package/dist/core/constraints/doc-freshness/runner.js +8 -3
- package/dist/core/constraints/doc-freshness/runner.js.map +1 -1
- package/dist/core/constraints/git-evidence.js +1 -1
- package/dist/core/constraints/git-evidence.js.map +1 -1
- package/dist/core/constraints/injection-drift.d.ts +7 -2
- package/dist/core/constraints/injection-drift.d.ts.map +1 -1
- package/dist/core/constraints/injection-drift.js +13 -7
- package/dist/core/constraints/injection-drift.js.map +1 -1
- package/dist/core/constraints/run-env.d.ts +92 -0
- package/dist/core/constraints/run-env.d.ts.map +1 -0
- package/dist/core/constraints/run-env.js +175 -0
- package/dist/core/constraints/run-env.js.map +1 -0
- package/dist/core/constraints/triggers.d.ts +22 -0
- package/dist/core/constraints/triggers.d.ts.map +1 -0
- package/dist/core/constraints/triggers.js +31 -0
- package/dist/core/constraints/triggers.js.map +1 -0
- package/dist/core/effective-constraints.d.ts +13 -4
- package/dist/core/effective-constraints.d.ts.map +1 -1
- package/dist/core/effective-constraints.js +16 -6
- package/dist/core/effective-constraints.js.map +1 -1
- package/dist/core/effective-set.d.ts +8 -15
- package/dist/core/effective-set.d.ts.map +1 -1
- package/dist/core/effective-set.js +7 -12
- package/dist/core/effective-set.js.map +1 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/project-config-loader.d.ts +39 -17
- package/dist/core/project-config-loader.d.ts.map +1 -1
- package/dist/core/project-config-loader.js +51 -122
- package/dist/core/project-config-loader.js.map +1 -1
- package/dist/core/validators/check-handlers/http.d.ts +2 -2
- package/dist/core/validators/check-handlers/http.d.ts.map +1 -1
- package/dist/core/validators/check-handlers/http.js +12 -7
- package/dist/core/validators/check-handlers/http.js.map +1 -1
- package/dist/core/validators/index.d.ts +1 -1
- package/dist/core/validators/index.d.ts.map +1 -1
- package/dist/core/validators/passes-gate.d.ts.map +1 -1
- package/dist/core/validators/passes-gate.js +2 -2
- package/dist/core/validators/passes-gate.js.map +1 -1
- package/dist/failure/classifier.d.ts +1 -1
- package/dist/failure/classifier.d.ts.map +1 -1
- package/dist/failure/classifier.js +8 -8
- package/dist/failure/classifier.js.map +1 -1
- package/dist/failure/index.d.ts +2 -1
- package/dist/failure/index.d.ts.map +1 -1
- package/dist/failure/index.js +9 -17
- package/dist/failure/index.js.map +1 -1
- package/dist/failure/recorder.d.ts +1 -1
- package/dist/failure/recorder.d.ts.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 +3 -2
- package/dist/gates/checker-gate.js.map +1 -1
- package/dist/gates/command.d.ts +10 -4
- package/dist/gates/command.d.ts.map +1 -1
- package/dist/gates/command.js +36 -62
- package/dist/gates/command.js.map +1 -1
- package/dist/gates/contract.d.ts.map +1 -1
- package/dist/gates/contract.js +0 -4
- package/dist/gates/contract.js.map +1 -1
- package/dist/gates/definitions.d.ts +2 -1
- package/dist/gates/definitions.d.ts.map +1 -1
- package/dist/gates/definitions.js +6 -5
- package/dist/gates/definitions.js.map +1 -1
- package/dist/gates/index.d.ts +0 -4
- package/dist/gates/index.d.ts.map +1 -1
- package/dist/gates/index.js +1 -6
- package/dist/gates/index.js.map +1 -1
- package/dist/gates/performance.d.ts.map +1 -1
- package/dist/gates/performance.js +0 -4
- package/dist/gates/performance.js.map +1 -1
- package/dist/gates/runner.d.ts +1 -1
- package/dist/gates/runner.js +1 -1
- package/dist/gates/security.d.ts +1 -1
- package/dist/gates/security.d.ts.map +1 -1
- package/dist/gates/security.js +5 -6
- package/dist/gates/security.js.map +1 -1
- package/dist/gates/types.d.ts +14 -17
- package/dist/gates/types.d.ts.map +1 -1
- package/dist/gates/types.js.map +1 -1
- package/dist/hooks/bootstrap.d.ts +6 -4
- package/dist/hooks/bootstrap.d.ts.map +1 -1
- package/dist/hooks/bootstrap.js +25 -13
- package/dist/hooks/bootstrap.js.map +1 -1
- package/dist/hooks/config.d.ts +6 -2
- package/dist/hooks/config.d.ts.map +1 -1
- package/dist/hooks/config.js +5 -1
- package/dist/hooks/config.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +0 -15
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/pipeline.d.ts.map +1 -1
- package/dist/hooks/pipeline.js +2 -4
- package/dist/hooks/pipeline.js.map +1 -1
- package/dist/hooks/registry.d.ts +11 -8
- package/dist/hooks/registry.d.ts.map +1 -1
- package/dist/hooks/registry.js +22 -7
- package/dist/hooks/registry.js.map +1 -1
- package/dist/hooks/types.d.ts +23 -7
- package/dist/hooks/types.d.ts.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/knowledge/audit-scoring.d.ts +87 -0
- package/dist/knowledge/audit-scoring.d.ts.map +1 -0
- package/dist/knowledge/audit-scoring.js +470 -0
- package/dist/knowledge/audit-scoring.js.map +1 -0
- package/dist/knowledge/audit.d.ts +11 -59
- package/dist/knowledge/audit.d.ts.map +1 -1
- package/dist/knowledge/audit.js +47 -522
- package/dist/knowledge/audit.js.map +1 -1
- package/dist/knowledge/import.d.ts.map +1 -1
- package/dist/knowledge/import.js +2 -0
- package/dist/knowledge/import.js.map +1 -1
- package/dist/knowledge/index-generator.d.ts.map +1 -1
- package/dist/knowledge/index-generator.js +4 -5
- package/dist/knowledge/index-generator.js.map +1 -1
- package/dist/knowledge/index.d.ts +3 -2
- package/dist/knowledge/index.d.ts.map +1 -1
- package/dist/knowledge/index.js +3 -16
- package/dist/knowledge/index.js.map +1 -1
- package/dist/knowledge/ingest.js +1 -1
- package/dist/knowledge/ingest.js.map +1 -1
- package/dist/knowledge/lifecycle.d.ts.map +1 -1
- package/dist/knowledge/lifecycle.js +4 -2
- package/dist/knowledge/lifecycle.js.map +1 -1
- package/dist/knowledge/migration.d.ts +3 -0
- package/dist/knowledge/migration.d.ts.map +1 -1
- package/dist/knowledge/migration.js +8 -2
- package/dist/knowledge/migration.js.map +1 -1
- package/dist/knowledge/query.d.ts +6 -0
- package/dist/knowledge/query.d.ts.map +1 -1
- package/dist/knowledge/query.js +8 -2
- package/dist/knowledge/query.js.map +1 -1
- package/dist/knowledge/reference-tracker.d.ts.map +1 -1
- package/dist/knowledge/reference-tracker.js +4 -6
- package/dist/knowledge/reference-tracker.js.map +1 -1
- package/dist/knowledge/store.d.ts +22 -16
- package/dist/knowledge/store.d.ts.map +1 -1
- package/dist/knowledge/store.js +53 -12
- package/dist/knowledge/store.js.map +1 -1
- package/dist/knowledge/tree-walker.d.ts +19 -0
- package/dist/knowledge/tree-walker.d.ts.map +1 -0
- package/dist/knowledge/tree-walker.js +30 -0
- package/dist/knowledge/tree-walker.js.map +1 -0
- package/dist/knowledge/types.d.ts +16 -0
- package/dist/knowledge/types.d.ts.map +1 -1
- package/dist/monitoring/traces.d.ts +5 -3
- package/dist/monitoring/traces.d.ts.map +1 -1
- package/dist/monitoring/traces.js +19 -5
- package/dist/monitoring/traces.js.map +1 -1
- package/dist/test-setup/jsonl-fake-fs.d.ts +30 -0
- package/dist/test-setup/jsonl-fake-fs.d.ts.map +1 -0
- package/dist/test-setup/jsonl-fake-fs.js +49 -0
- package/dist/test-setup/jsonl-fake-fs.js.map +1 -0
- package/dist/tools/index.d.ts +4 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -15
- package/dist/tools/index.js.map +1 -1
- package/dist/types/checkpoint.d.ts +5 -0
- package/dist/types/checkpoint.d.ts.map +1 -1
- package/dist/types/passes-gate.d.ts +0 -13
- package/dist/types/passes-gate.d.ts.map +1 -1
- package/dist/types/project-config.d.ts +18 -0
- package/dist/types/project-config.d.ts.map +1 -1
- package/dist/types/trace.d.ts +13 -4
- package/dist/types/trace.d.ts.map +1 -1
- package/dist/types/trace.js +4 -3
- package/dist/types/trace.js.map +1 -1
- package/dist/utils/exec.d.ts +4 -27
- package/dist/utils/exec.d.ts.map +1 -1
- package/dist/utils/exec.js +4 -94
- package/dist/utils/exec.js.map +1 -1
- package/dist/utils/jsonl.d.ts +17 -7
- package/dist/utils/jsonl.d.ts.map +1 -1
- package/dist/utils/jsonl.js +144 -17
- package/dist/utils/jsonl.js.map +1 -1
- package/dist/utils/numeric-flag.d.ts +44 -0
- package/dist/utils/numeric-flag.d.ts.map +1 -0
- package/dist/utils/numeric-flag.js +62 -0
- package/dist/utils/numeric-flag.js.map +1 -0
- package/package.json +1 -1
- package/src/CONTEXT.md +5 -2
- package/src/__tests__/acceptance-gate.test.ts +7 -4
- package/src/__tests__/checker-extra.test.ts +3 -2
- package/src/__tests__/checker.test.ts +4 -3
- package/src/__tests__/checkpoint.test.ts +26 -9
- package/src/__tests__/context-files-resolution.test.ts +29 -15
- package/src/__tests__/contract-gate.test.ts +19 -40
- package/src/__tests__/error-classifier.test.ts +1 -1
- package/src/__tests__/exec.test.ts +45 -107
- package/src/__tests__/failure-recorder.test.ts +7 -5
- package/src/__tests__/hooks-pipeline.test.ts +34 -47
- package/src/__tests__/layering.test.ts +217 -25
- package/src/__tests__/passes-gate.test.ts +9 -4
- package/src/__tests__/performance-gate.test.ts +3 -15
- package/src/__tests__/project-config-loader-extra.test.ts +31 -57
- package/src/__tests__/project-config-loader.test.ts +6 -3
- package/src/__tests__/public-exports.test.ts +27 -6
- package/src/__tests__/public-type-surface.test.ts +360 -0
- package/src/__tests__/public-value-surface.test.ts +182 -0
- package/src/__tests__/review-gate.test.ts +4 -6
- package/src/__tests__/security-gate.test.ts +5 -20
- package/src/__tests__/skip-semantics.test.ts +5 -3
- package/src/__tests__/spec-validator.test.ts +3 -2
- package/src/__tests__/sub-barrels-explicit.test.ts +87 -0
- package/src/__tests__/test-fixture-hygiene.test.ts +53 -0
- package/src/__tests__/trace-analyzer-extra.test.ts +5 -3
- package/src/__tests__/trace-analyzer.test.ts +5 -3
- package/src/__tests__/trace-collector.test.ts +5 -3
- package/src/agents/index.ts +13 -2
- package/src/cli/__tests__/gate-command.test.ts +162 -0
- package/src/cli/commands/CONTEXT.md +29 -5
- package/src/cli/commands/__tests__/acceptance.test.ts +24 -25
- package/src/cli/commands/__tests__/bin-exit-mapping.test.ts +15 -0
- package/src/cli/commands/__tests__/check-drift.test.ts +42 -1
- package/src/cli/commands/__tests__/check-read-count.test.ts +167 -0
- package/src/cli/commands/__tests__/check-skip-output.test.ts +4 -1
- package/src/cli/commands/__tests__/check.test.ts +43 -36
- package/src/cli/commands/__tests__/command-gate-dead-options.test.ts +60 -0
- package/src/cli/commands/__tests__/command.test.ts +33 -17
- package/src/cli/commands/__tests__/constraints-retire.test.ts +52 -0
- package/src/cli/commands/__tests__/context-syncer.test.ts +141 -0
- package/src/cli/commands/__tests__/contract.test.ts +20 -20
- package/src/cli/commands/__tests__/failure.test.ts +5 -4
- package/src/cli/commands/__tests__/gate-decision.ts +30 -0
- package/src/cli/commands/__tests__/init-dead-options.test.ts +50 -0
- package/src/cli/commands/__tests__/init-governance-io.test.ts +139 -0
- package/src/cli/commands/__tests__/init-injection.test.ts +3 -3
- package/src/cli/commands/__tests__/init-ondisk.test.ts +867 -0
- package/src/cli/commands/__tests__/init.test.ts +82 -6
- package/src/cli/commands/__tests__/knowledge-audit-threshold.test.ts +146 -0
- package/src/cli/commands/__tests__/knowledge-flywheel-consistency.test.ts +1 -1
- package/src/cli/commands/__tests__/knowledge-tone-mapping.test.ts +244 -0
- package/src/cli/commands/__tests__/knowledge-view.test.ts +839 -0
- package/src/cli/commands/__tests__/knowledge.test.ts +33 -15
- package/src/cli/commands/__tests__/numeric-flag-assembly.test.ts +368 -0
- package/src/cli/commands/__tests__/passes-gate-dead-options.test.ts +89 -1
- package/src/cli/commands/__tests__/performance.test.ts +19 -21
- package/src/cli/commands/__tests__/posteval-plan.test.ts +5 -3
- package/src/cli/commands/__tests__/pre-push-hook.test.ts +181 -0
- package/src/cli/commands/__tests__/project-path-anchoring.test.ts +95 -2
- package/src/cli/commands/__tests__/project-path-convention.test.ts +103 -25
- package/src/cli/commands/__tests__/registry.test.ts +2 -0
- package/src/cli/commands/__tests__/report.test.ts +23 -1
- package/src/cli/commands/__tests__/review.test.ts +10 -17
- package/src/cli/commands/__tests__/scaffold.test.ts +505 -0
- package/src/cli/commands/__tests__/security-default-scan.test.ts +75 -0
- package/src/cli/commands/__tests__/security.test.ts +21 -24
- package/src/cli/commands/__tests__/spec-baseline-check.test.ts +3 -2
- package/src/cli/commands/__tests__/spec-baseline-index-cap.test.ts +131 -0
- package/src/cli/commands/__tests__/spec-baseline-read-count.test.ts +325 -0
- package/src/cli/commands/__tests__/sync-docs-agents.test.ts +19 -4
- package/src/cli/commands/__tests__/sync-docs-context-drift.test.ts +232 -0
- package/src/cli/commands/__tests__/sync-docs-module-order.test.ts +111 -0
- package/src/cli/commands/__tests__/sync-docs-read-count.test.ts +192 -0
- package/src/cli/commands/__tests__/sync-docs.test.ts +3 -2
- package/src/cli/commands/__tests__/validate.test.ts +1 -48
- package/src/cli/commands/acceptance.ts +24 -29
- package/src/cli/commands/check.ts +40 -17
- package/src/cli/commands/command.ts +9 -8
- package/src/cli/commands/constraints-retire.ts +57 -70
- package/src/cli/commands/contract.ts +44 -47
- package/src/cli/commands/definitions.ts +12 -6
- package/src/cli/commands/failure.ts +16 -3
- package/src/cli/commands/init.ts +242 -389
- package/src/cli/commands/knowledge-view.ts +224 -0
- package/src/cli/commands/knowledge.ts +643 -448
- package/src/cli/commands/passes-gate.ts +12 -3
- package/src/cli/commands/performance.ts +31 -38
- package/src/cli/commands/report.ts +3 -2
- package/src/cli/commands/review.ts +22 -28
- package/src/cli/commands/scaffold-templates.ts +406 -0
- package/src/cli/commands/scaffold.ts +302 -0
- package/src/cli/commands/security.ts +27 -23
- package/src/cli/commands/spec-baseline-check.ts +158 -33
- package/src/cli/commands/sync-docs/__tests__/context-export-surface.test.ts +102 -0
- package/src/cli/commands/sync-docs/__tests__/module-descriptions.test.ts +196 -0
- package/src/cli/commands/sync-docs/context-syncer.ts +137 -31
- package/src/cli/commands/sync-docs/index.ts +103 -28
- package/src/cli/commands/sync-docs/project-reader.ts +51 -7
- package/src/cli/commands/validate.ts +1 -104
- package/src/cli/gate-command.ts +87 -0
- package/src/completion-checkers/index.ts +10 -1
- package/src/context/CONTEXT.md +2 -1
- package/src/context/__tests__/knowledge-injector.test.ts +27 -0
- package/src/context/__tests__/session-manager.test.ts +19 -12
- package/src/context/knowledge-injector.ts +14 -7
- package/src/core/CONTEXT.md +10 -7
- package/src/core/__tests__/effective-set.test.ts +36 -60
- package/src/core/constraints/__tests__/context-reconcile.test.ts +246 -0
- package/src/core/constraints/__tests__/run-env.test.ts +377 -0
- package/src/core/constraints/__tests__/triggers.test.ts +70 -0
- package/src/core/constraints/agent-prompt-renderer.ts +1 -1
- package/src/core/constraints/capabilities-reconcile.ts +28 -4
- package/src/core/constraints/check-cache.ts +1 -1
- package/src/core/constraints/checker.ts +30 -14
- package/src/core/constraints/checkers/__tests__/context-doc-sync.test.ts +8 -3
- package/src/core/constraints/checkers/__tests__/governance-presence.test.ts +16 -7
- package/src/core/constraints/checkers/__tests__/no-hardcoded-credentials.test.ts +2 -1
- package/src/core/constraints/checkers/capability-sync.ts +27 -28
- package/src/core/constraints/checkers/context-doc-sync.ts +9 -7
- package/src/core/constraints/checkers/docs-freshness.ts +28 -33
- package/src/core/constraints/checkers/governance-presence.ts +10 -6
- package/src/core/constraints/checkers/types.ts +14 -8
- package/src/core/constraints/context-builder.ts +35 -26
- package/src/core/constraints/context-reconcile.ts +200 -0
- package/src/core/constraints/doc-freshness/__tests__/runner.test.ts +25 -0
- package/src/core/constraints/doc-freshness/runner.ts +18 -4
- package/src/core/constraints/git-evidence.ts +1 -1
- package/src/core/constraints/injection-drift.ts +19 -8
- package/src/core/constraints/run-env.ts +207 -0
- package/src/core/constraints/triggers.ts +33 -0
- package/src/core/effective-constraints.ts +17 -6
- package/src/core/effective-set.ts +8 -24
- package/src/core/index.ts +2 -1
- package/src/core/project-config-loader.ts +54 -102
- package/src/core/validators/__tests__/http-retry-sleep.test.ts +231 -0
- package/src/core/validators/check-handlers/http.ts +18 -7
- package/src/core/validators/index.ts +0 -1
- package/src/core/validators/passes-gate.ts +2 -3
- package/src/failure/CONTEXT.md +2 -1
- package/src/failure/classifier.ts +2 -2
- package/src/failure/index.ts +14 -2
- package/src/failure/recorder.ts +1 -1
- package/src/gates/CONTEXT.md +13 -7
- package/src/gates/__tests__/checker-gate.test.ts +1 -1
- package/src/gates/__tests__/command-single-predicate.test.ts +135 -0
- package/src/gates/__tests__/command.test.ts +8 -15
- package/src/gates/__tests__/contract.test.ts +5 -5
- package/src/gates/__tests__/gate-interface.test.ts +0 -17
- package/src/gates/__tests__/performance.test.ts +0 -13
- package/src/gates/__tests__/review.test.ts +0 -1
- package/src/gates/__tests__/runner.test.ts +1 -1
- package/src/gates/__tests__/security-default-scan.test.ts +97 -0
- package/src/gates/__tests__/security.test.ts +0 -13
- package/src/gates/checker-gate.ts +3 -2
- package/src/gates/command.ts +51 -74
- package/src/gates/contract.ts +0 -5
- package/src/gates/definitions.ts +6 -5
- package/src/gates/index.ts +0 -5
- package/src/gates/performance.ts +1 -6
- package/src/gates/runner.ts +1 -1
- package/src/gates/security.ts +9 -11
- package/src/gates/types.ts +20 -23
- package/src/hooks/CONTEXT.md +10 -9
- package/src/hooks/__tests__/bootstrap.test.ts +29 -6
- package/src/hooks/__tests__/pipeline.test.ts +28 -17
- package/src/hooks/__tests__/registry.test.ts +51 -3
- package/src/hooks/bootstrap.ts +35 -15
- package/src/hooks/config.ts +6 -2
- package/src/hooks/index.ts +10 -1
- package/src/hooks/pipeline.ts +4 -6
- package/src/hooks/registry.ts +31 -12
- package/src/hooks/types.ts +24 -7
- package/src/index.ts +1 -3
- package/src/knowledge/CONTEXT.md +14 -7
- package/src/knowledge/__tests__/audit-labels.test.ts +8 -5
- package/src/knowledge/__tests__/audit-scoring.test.ts +230 -0
- package/src/knowledge/__tests__/audit-write-count.test.ts +131 -0
- package/src/knowledge/__tests__/audit.test.ts +291 -208
- package/src/knowledge/__tests__/doctor.test.ts +3 -2
- package/src/knowledge/__tests__/ingest.test.ts +3 -2
- package/src/knowledge/__tests__/lifecycle.test.ts +57 -2
- package/src/knowledge/__tests__/migration.test.ts +35 -6
- package/src/knowledge/__tests__/query.test.ts +3 -2
- package/src/knowledge/__tests__/reference-tracker.test.ts +23 -2
- package/src/knowledge/__tests__/store.test.ts +149 -4
- package/src/knowledge/__tests__/tree-walker.test.ts +132 -0
- package/src/knowledge/audit-scoring.ts +589 -0
- package/src/knowledge/audit.ts +55 -599
- package/src/knowledge/import.ts +2 -0
- package/src/knowledge/index-generator.ts +4 -6
- package/src/knowledge/index.ts +27 -2
- package/src/knowledge/ingest.ts +1 -1
- package/src/knowledge/lifecycle.ts +5 -2
- package/src/knowledge/migration.ts +8 -2
- package/src/knowledge/query.ts +8 -1
- package/src/knowledge/reference-tracker.ts +5 -7
- package/src/knowledge/store.ts +75 -16
- package/src/knowledge/tree-walker.ts +29 -0
- package/src/knowledge/types.ts +19 -0
- package/src/monitoring/CONTEXT.md +5 -2
- package/src/monitoring/__tests__/context-tracker.test.ts +16 -8
- package/src/monitoring/__tests__/trace-file-anchoring.test.ts +80 -0
- package/src/monitoring/traces.ts +19 -5
- package/src/release/CONTEXT.md +1 -1
- package/src/release/__tests__/integrity.test.ts +21 -12
- package/src/test-setup/__tests__/jsonl-fake-fs.test.ts +98 -0
- package/src/test-setup/jsonl-fake-fs.ts +59 -0
- package/src/tools/index.ts +5 -1
- package/src/types/checkpoint.ts +6 -0
- package/src/types/passes-gate.ts +0 -17
- package/src/types/project-config.ts +21 -0
- package/src/types/trace.ts +14 -4
- package/src/utils/__tests__/file-walk.test.ts +3 -2
- package/src/utils/__tests__/jsonl-bounded-read.test.ts +106 -0
- package/src/utils/__tests__/jsonl-skip-disposition.test.ts +10 -6
- package/src/utils/__tests__/jsonl.test.ts +61 -14
- package/src/utils/__tests__/numeric-flag.test.ts +80 -0
- package/src/utils/__tests__/package-version.test.ts +2 -2
- package/src/utils/exec.ts +4 -64
- package/src/utils/jsonl.ts +159 -20
- package/src/utils/numeric-flag.ts +64 -0
- package/dist/failure/types.d.ts +0 -9
- package/dist/failure/types.d.ts.map +0 -1
- package/dist/failure/types.js +0 -25
- package/dist/failure/types.js.map +0 -1
- package/dist/gates/effective-gates.d.ts +0 -30
- package/dist/gates/effective-gates.d.ts.map +0 -1
- package/dist/gates/effective-gates.js +0 -81
- package/dist/gates/effective-gates.js.map +0 -1
- package/src/failure/types.ts +0 -9
- package/src/gates/__tests__/effective-gates.test.ts +0 -77
- package/src/gates/effective-gates.ts +0 -99
|
@@ -10,7 +10,8 @@ import * as path from 'path';
|
|
|
10
10
|
import { execAsync } from '../../utils/exec';
|
|
11
11
|
import { PassesGate, detectTestCommand } from '../../core/validators/passes-gate';
|
|
12
12
|
import type { PassesGateConfig } from '../../types/passes-gate';
|
|
13
|
-
import { log, processIO, type CommandIO, type CommandResult } from '../command-contract';
|
|
13
|
+
import { log, logError, processIO, type CommandIO, type CommandResult } from '../command-contract';
|
|
14
|
+
import { numericFlagMessage, parseNumericFlag } from '../../utils/numeric-flag';
|
|
14
15
|
|
|
15
16
|
export interface PassesGateOptions {
|
|
16
17
|
/** 测试命令 */
|
|
@@ -92,16 +93,24 @@ export async function runPassesGate(
|
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
/**
|
|
95
|
-
* --coverage 路由入口(候选7):projectPath 兜底 +
|
|
96
|
+
* --coverage 路由入口(候选7):projectPath 兜底 + 阈值装配窄化,
|
|
96
97
|
* 自 definitions.ts 的 optionRoutes args 闭包移回命令模块。
|
|
98
|
+
* `--coverage-threshold` 给到的恒是字符串(缺省 '80' 也是),脏输入 fail-loud
|
|
99
|
+
* (harness#154,原先 parseInt 出 NaN → `totalCoverage >= NaN` 恒 false →
|
|
100
|
+
* 打出自证异常的「覆盖率不足 (x% < NaN%)」),且先于任何覆盖率执行。
|
|
97
101
|
*/
|
|
98
102
|
export async function coverageCheck(
|
|
99
103
|
options: Record<string, unknown>,
|
|
100
104
|
io: CommandIO = processIO,
|
|
101
105
|
): Promise<CommandResult> {
|
|
106
|
+
const threshold = parseNumericFlag(options.coverageThreshold as string | undefined, 'int');
|
|
107
|
+
if (!threshold.ok) {
|
|
108
|
+
logError(io, numericFlagMessage('--coverage-threshold', threshold.raw, 'int'));
|
|
109
|
+
return { kind: 'usage-error', reason: `passes-gate --coverage-threshold 非法阈值: "${threshold.raw}"` };
|
|
110
|
+
}
|
|
102
111
|
return checkCoverage(
|
|
103
112
|
(options.projectPath as string) || process.cwd(),
|
|
104
|
-
|
|
113
|
+
threshold.value,
|
|
105
114
|
io,
|
|
106
115
|
);
|
|
107
116
|
}
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
import chalk from 'chalk';
|
|
8
8
|
import { PerformanceGate, type ExtendedPerformanceGateConfig } from '../../gates/performance';
|
|
9
|
-
import type {
|
|
9
|
+
import type { PerformanceThresholds } from '../../gates/types';
|
|
10
10
|
import { log, processIO, type CommandIO, type CommandResult } from '../command-contract';
|
|
11
|
+
import { reportGateDecision, reportGateError } from '../gate-command';
|
|
11
12
|
|
|
12
13
|
export interface PerformanceOptions {
|
|
13
14
|
/** 项目路径 */
|
|
@@ -54,46 +55,38 @@ export async function performance(
|
|
|
54
55
|
const gate = new PerformanceGate(config);
|
|
55
56
|
|
|
56
57
|
try {
|
|
57
|
-
const
|
|
58
|
+
const decision = await gate.evaluate({ projectPath });
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
return reportGateDecision(
|
|
61
|
+
io,
|
|
62
|
+
{
|
|
63
|
+
gateId: 'performance',
|
|
64
|
+
label: '性能门控',
|
|
65
|
+
onPass: (r) => {
|
|
66
|
+
if (!r.details?.metrics) return [];
|
|
67
|
+
const metrics = r.details.metrics as any;
|
|
68
|
+
const lines = ['', chalk.gray('性能指标:')];
|
|
62
69
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
70
|
+
if (metrics.coverage !== undefined) {
|
|
71
|
+
const threshold = options.coverageThreshold || 80;
|
|
72
|
+
lines.push(chalk.gray(` 覆盖率: ${metrics.coverage.toFixed(2)}% ${metrics.coverage >= threshold ? '✅' : '❌'}`));
|
|
73
|
+
}
|
|
67
74
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
log(io, chalk.gray(` 覆盖率: ${metrics.coverage.toFixed(2)}% ${status}`));
|
|
73
|
-
}
|
|
75
|
+
if (metrics.bundleSize !== undefined) {
|
|
76
|
+
const thresholdKB = options.bundleThreshold || 500;
|
|
77
|
+
lines.push(chalk.gray(` 打包大小: ${metrics.bundleSize} KB ${metrics.bundleSize <= thresholdKB ? '✅' : '❌'}`));
|
|
78
|
+
}
|
|
74
79
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
(result.details.failures as string[]).forEach((failure: string) => {
|
|
87
|
-
log(io, chalk.red(` - ${failure}`));
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
return { kind: 'fail', reason: `performance gate denied: ${result.message}` };
|
|
91
|
-
}
|
|
92
|
-
return { kind: 'ok' };
|
|
93
|
-
} catch (error: any) {
|
|
94
|
-
log(io);
|
|
95
|
-
log(io, chalk.red('❌ 性能门控检查出错'));
|
|
96
|
-
log(io, chalk.red(` ${error.message}`));
|
|
97
|
-
return { kind: 'fail', reason: `performance gate error: ${error.message}` };
|
|
80
|
+
return lines;
|
|
81
|
+
},
|
|
82
|
+
onFail: (r) =>
|
|
83
|
+
r.details?.failures
|
|
84
|
+
? (r.details.failures as string[]).map((failure: string) => chalk.red(` - ${failure}`))
|
|
85
|
+
: [],
|
|
86
|
+
},
|
|
87
|
+
decision
|
|
88
|
+
);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
return reportGateError(io, 'performance', '性能门控', error);
|
|
98
91
|
}
|
|
99
92
|
}
|
|
@@ -8,7 +8,7 @@ import chalk from 'chalk';
|
|
|
8
8
|
import * as fs from 'fs/promises';
|
|
9
9
|
import { ConstraintChecker } from '../../core/constraints/checker';
|
|
10
10
|
import { IRON_LAWS, GUIDELINES, PROMPTS } from '../../core/constraints/definitions';
|
|
11
|
-
import {
|
|
11
|
+
import { TraceCollector } from '../../monitoring/traces';
|
|
12
12
|
import type { ConstraintContext } from '../../types/constraint';
|
|
13
13
|
import { log, processIO, type CommandIO, type CommandResult } from '../command-contract';
|
|
14
14
|
|
|
@@ -48,7 +48,8 @@ export async function report(options: ReportOptions, io: CommandIO = processIO):
|
|
|
48
48
|
|
|
49
49
|
const projectPath = options.projectPath || process.cwd();
|
|
50
50
|
// trace 记录器经构造参数接线(harness#88):本命令是组合根
|
|
51
|
-
|
|
51
|
+
// #139:收集器锚根构造——不传 projectPath 时 trace 会落进调用方 cwd,B 侧读不到
|
|
52
|
+
const checker = new ConstraintChecker(new TraceCollector({ projectPath }));
|
|
52
53
|
|
|
53
54
|
const allConstraints = { ...IRON_LAWS, ...GUIDELINES, ...PROMPTS };
|
|
54
55
|
const totalConstraints = Object.keys(allConstraints).length;
|
|
@@ -8,6 +8,7 @@ import chalk from 'chalk';
|
|
|
8
8
|
import { execAsync } from '../../utils/exec';
|
|
9
9
|
import { ReviewGate } from '../../gates/review';
|
|
10
10
|
import { log, processIO, type CommandIO, type CommandResult } from '../command-contract';
|
|
11
|
+
import { reportGateDecision, reportGateError } from '../gate-command';
|
|
11
12
|
|
|
12
13
|
export interface ReviewOptions {
|
|
13
14
|
/** 项目路径 */
|
|
@@ -46,34 +47,27 @@ export async function review(
|
|
|
46
47
|
const { stdout: branch } = await execAsync('git rev-parse --abbrev-ref HEAD', { cwd: projectPath });
|
|
47
48
|
log(io, chalk.gray(`当前分支: ${branch.trim()}`));
|
|
48
49
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (error.message.includes('not a git repository')) {
|
|
72
|
-
log(io);
|
|
73
|
-
log(io, chalk.gray('提示: 此命令需要在 Git 仓库中运行'));
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return { kind: 'fail', reason: `review gate error: ${error.message}` };
|
|
50
|
+
const decision = await gate.evaluate({ projectPath });
|
|
51
|
+
|
|
52
|
+
return reportGateDecision(
|
|
53
|
+
io,
|
|
54
|
+
{
|
|
55
|
+
gateId: 'review',
|
|
56
|
+
label: '代码审查门控',
|
|
57
|
+
onPass: (r) =>
|
|
58
|
+
r.details
|
|
59
|
+
? [chalk.gray(` 审批: ${r.details.approvals ?? 0}, 变更请求: ${r.details.changesRequested ?? 0}`)]
|
|
60
|
+
: [],
|
|
61
|
+
onFail: (r) => (r.details?.suggestion ? [chalk.gray(` ${r.details.suggestion}`)] : []),
|
|
62
|
+
},
|
|
63
|
+
decision
|
|
64
|
+
);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
return reportGateError(io, 'review', '代码审查门控', error, (message) =>
|
|
67
|
+
message.includes('not a git repository')
|
|
68
|
+
? ['', chalk.gray('提示: 此命令需要在 Git 仓库中运行')]
|
|
69
|
+
: []
|
|
70
|
+
);
|
|
77
71
|
}
|
|
78
72
|
}
|
|
79
73
|
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 脚手架模板数据(harness#132)
|
|
3
|
+
*
|
|
4
|
+
* 受管文件的正文正本,纯数据 + 纯渲染,零 IO、零上色——落盘语义与文案在
|
|
5
|
+
* `scaffold.ts` 的 plan 里,本模块只回答「这个文件的内容是什么」。
|
|
6
|
+
*
|
|
7
|
+
* 刻意留在代码内而不落 `templates/` 目录:`templates/` 无运行时消费者
|
|
8
|
+
* (harness 自身不读它),发布完整性清单(`release/integrity.ts`)也不覆盖它。
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
import * as yaml from 'js-yaml';
|
|
13
|
+
import type { Checkpoint } from '../../types/checkpoint';
|
|
14
|
+
import type { CiPlatform } from '../../types/project-config';
|
|
15
|
+
|
|
16
|
+
/** Git pre-commit 片段(#103:打印片段与落盘 hook 的唯一正本) */
|
|
17
|
+
export const PRE_COMMIT_SNIPPET = `
|
|
18
|
+
echo "🔍 Running harness checks..."
|
|
19
|
+
|
|
20
|
+
STAGED=$(git diff --cached --name-only --diff-filter=ACMR 2>/dev/null || true)
|
|
21
|
+
|
|
22
|
+
# Harness 约束检查
|
|
23
|
+
npx @dommaker/harness check --staged
|
|
24
|
+
if [ $? -ne 0 ]; then
|
|
25
|
+
echo "❌ Iron law check failed"
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# Plan coverage check (via PostEval)
|
|
30
|
+
if command -v npx > /dev/null 2>&1; then
|
|
31
|
+
PLAN_FILES=$(echo "$STAGED" | grep -E 'plans/.*\\.md$|\\.plan\\.md$' || true)
|
|
32
|
+
if [ -n "$PLAN_FILES" ]; then
|
|
33
|
+
echo "📋 Checking plan coverage..."
|
|
34
|
+
for plan in $PLAN_FILES; do
|
|
35
|
+
npx @dommaker/harness posteval-plan "$plan" || {
|
|
36
|
+
echo "🛑 Plan coverage incomplete. See above for missed items."
|
|
37
|
+
exit 1
|
|
38
|
+
}
|
|
39
|
+
done
|
|
40
|
+
fi
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
echo "✅ All checks passed"
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
/** 落盘的 pre-commit hook = shebang + 说明行 + 共享片段 */
|
|
47
|
+
export function renderPreCommitHook(): string {
|
|
48
|
+
return `#!/bin/sh
|
|
49
|
+
# Harness pre-commit hook
|
|
50
|
+
${PRE_COMMIT_SNIPPET}`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Git pre-push 片段(harness#144;#103:打印片段与落盘 hook 的唯一正本)
|
|
55
|
+
*
|
|
56
|
+
* 三道决定都写在这段正文里,不再由代码补:
|
|
57
|
+
* - **整仓全量**:`check` 不带 `--staged`,加一道 `validate`——它拦的是
|
|
58
|
+
* `git commit --no-verify` 绕过 pre-commit 的内容,重复是设计使然;
|
|
59
|
+
* - **不做增量**:不解析 pre-push 从 stdin 收到的 `<local_ref> <local_oid>
|
|
60
|
+
* <remote_ref> <remote_oid>` 清单,无论推什么整仓过一遍;子进程也不给它读;
|
|
61
|
+
* - **不内建逃生机制**:没有环境变量开关、没有超时、没有「慢则降级」,
|
|
62
|
+
* 唯一的口子是 git 原生 `git push --no-verify`。
|
|
63
|
+
*/
|
|
64
|
+
export const PRE_PUSH_SNIPPET = `
|
|
65
|
+
echo "🔍 Running harness pre-push checks (whole repo)..."
|
|
66
|
+
|
|
67
|
+
# 分工:pre-commit 查暂存的(增量、快反馈),pre-push 查整仓的(全量、兜底)。
|
|
68
|
+
# 同一次改动跑两遍是设计使然——这道拦的是 git commit --no-verify 绕出去的内容。
|
|
69
|
+
# 本地 hook 只是自检与提醒,真正的门禁在服务端 CI;逃生口只有 git 原生 push --no-verify。
|
|
70
|
+
# 不解析 pre-push 从 stdin 收到的 ref 清单,子进程一律不给它读(< /dev/null)。
|
|
71
|
+
npx @dommaker/harness check < /dev/null
|
|
72
|
+
if [ $? -ne 0 ]; then
|
|
73
|
+
echo "❌ Iron law check failed"
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
npx @dommaker/harness validate < /dev/null
|
|
78
|
+
if [ $? -ne 0 ]; then
|
|
79
|
+
echo "❌ Validate failed"
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
echo "✅ All pre-push checks passed"
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
/** 落盘的 pre-push hook = shebang + 说明行 + 共享片段 */
|
|
87
|
+
export function renderPrePushHook(): string {
|
|
88
|
+
return `#!/bin/sh
|
|
89
|
+
# Harness pre-push hook
|
|
90
|
+
${PRE_PUSH_SNIPPET}`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ── GitLab CI(harness#143):与 GH 版对仗的接线形状 ──────────────────────
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* GitLab 任务的触发条件(决议 ⑥:用 `rules:` 不用过时的 `only:`)
|
|
97
|
+
*
|
|
98
|
+
* MR 事件 + main/master 分支 push,与 GH 版 `on:` 段一一对应。三个任务各自带一份
|
|
99
|
+
* ——GitLab 的 `default:` 不支持 `rules`,自建实例版本参差,不赌语法糖。
|
|
100
|
+
*/
|
|
101
|
+
const GITLAB_RULES = ` rules:
|
|
102
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
103
|
+
- if: $CI_COMMIT_BRANCH == "main"
|
|
104
|
+
- if: $CI_COMMIT_BRANCH == "master"
|
|
105
|
+
`;
|
|
106
|
+
|
|
107
|
+
/** `.gitlab-ci.yml` 文件头:harness 只拥有其下的 `harness-*` 任务 */
|
|
108
|
+
const GITLAB_CI_HEADER = `# 由 harness init 生成 —— 以下 harness-* 任务是 harness 的 CI 接线
|
|
109
|
+
# 门禁真正生效还需在 GitLab 侧开分支保护:pipeline 成功才允许合并
|
|
110
|
+
|
|
111
|
+
image: node:20
|
|
112
|
+
|
|
113
|
+
stages:
|
|
114
|
+
- test
|
|
115
|
+
|
|
116
|
+
`;
|
|
117
|
+
|
|
118
|
+
/** GitLab harness-check 任务(`--print-snippets` 打印的 job 片段即此份) */
|
|
119
|
+
export const GITLAB_CI_SNIPPET = `harness-check:
|
|
120
|
+
stage: test
|
|
121
|
+
script:
|
|
122
|
+
- npm ci
|
|
123
|
+
- npx @dommaker/harness check
|
|
124
|
+
- npx @dommaker/harness validate
|
|
125
|
+
- npx @dommaker/harness passes-gate
|
|
126
|
+
${GITLAB_RULES}`;
|
|
127
|
+
|
|
128
|
+
/** harness 拥有的 GitLab 任务全集(治理档在场时含治理任务)——落盘正文与冲突片段共用 */
|
|
129
|
+
export function renderGitLabCiJobs(governanceLevel?: string): string {
|
|
130
|
+
return governanceLevel
|
|
131
|
+
? `${GITLAB_CI_SNIPPET}\n${renderGovernanceWorkflow(governanceLevel, 'gitlab')}`
|
|
132
|
+
: GITLAB_CI_SNIPPET;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** `.gitlab-ci.yml` 落盘全文正本(= 文件头 + harness 拥有的任务) */
|
|
136
|
+
export function renderGitLabCiFile(governanceLevel?: string): string {
|
|
137
|
+
return `${GITLAB_CI_HEADER}${renderGitLabCiJobs(governanceLevel)}`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** harness-check.yml 全文(落盘正文,冲突时打印的也是这一份) */
|
|
141
|
+
export const HARNESS_CHECK_WORKFLOW = `name: Harness Check
|
|
142
|
+
|
|
143
|
+
on:
|
|
144
|
+
push:
|
|
145
|
+
branches: [main, master]
|
|
146
|
+
pull_request:
|
|
147
|
+
branches: [main, master]
|
|
148
|
+
|
|
149
|
+
jobs:
|
|
150
|
+
harness-check:
|
|
151
|
+
runs-on: ubuntu-latest
|
|
152
|
+
|
|
153
|
+
steps:
|
|
154
|
+
- uses: actions/checkout@v4
|
|
155
|
+
|
|
156
|
+
- name: Setup Node.js
|
|
157
|
+
uses: actions/setup-node@v4
|
|
158
|
+
with:
|
|
159
|
+
node-version: '20'
|
|
160
|
+
|
|
161
|
+
- name: Install dependencies
|
|
162
|
+
run: npm ci
|
|
163
|
+
|
|
164
|
+
- name: Run harness check
|
|
165
|
+
run: npx @dommaker/harness check
|
|
166
|
+
|
|
167
|
+
- name: Run harness validate
|
|
168
|
+
run: npx @dommaker/harness validate
|
|
169
|
+
|
|
170
|
+
- name: Run harness passes-gate
|
|
171
|
+
run: npx @dommaker/harness passes-gate
|
|
172
|
+
`;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* GitHub Actions job 片段(`init --print-snippets` 的片段视图,harness#153)
|
|
176
|
+
*
|
|
177
|
+
* 由上面的落盘正本裁出 `jobs:` 段之后的一切,**不是第二份手抄文本**——它曾独立存在并
|
|
178
|
+
* 少掉 `validate` / `passes-gate` 两道门禁,照抄的用户拿到比同版本 `harness init` 弱一半
|
|
179
|
+
* 的 CI(#103 判据的第三种形态)。形状与 GitLab 侧对仗:打印的是正本的 job 段。
|
|
180
|
+
*/
|
|
181
|
+
export const GITHUB_ACTIONS_SNIPPET = HARNESS_CHECK_WORKFLOW.slice(
|
|
182
|
+
HARNESS_CHECK_WORKFLOW.indexOf(' harness-check:'),
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* 治理 CI 面正文
|
|
187
|
+
*
|
|
188
|
+
* `minimal` 档不带 docs 新鲜度检查(其余档位带,且失败不阻断)。平台只改变接线形状,
|
|
189
|
+
* 三条命令与档位语义一致(harness#143):GitLab 侧的「失败不阻断」= `allow_failure: true`,
|
|
190
|
+
* 且因每个任务都是全新容器,docs 检查单列一个任务而非 GH 的一个 step。
|
|
191
|
+
*/
|
|
192
|
+
export function renderGovernanceWorkflow(level: string, platform: CiPlatform): string {
|
|
193
|
+
if (platform === 'gitlab') {
|
|
194
|
+
const docsJob = level === 'minimal'
|
|
195
|
+
? ''
|
|
196
|
+
: `
|
|
197
|
+
harness-docs-freshness:
|
|
198
|
+
stage: test
|
|
199
|
+
script:
|
|
200
|
+
- npm ci
|
|
201
|
+
- npx @dommaker/harness sync-docs --check
|
|
202
|
+
${GITLAB_RULES} allow_failure: true
|
|
203
|
+
`;
|
|
204
|
+
return `harness-governance:
|
|
205
|
+
stage: test
|
|
206
|
+
script:
|
|
207
|
+
- npm ci
|
|
208
|
+
- npx @dommaker/harness check
|
|
209
|
+
- npx @dommaker/harness passes-gate
|
|
210
|
+
${GITLAB_RULES}${docsJob}`;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const docsCheckStep = level !== 'minimal'
|
|
214
|
+
? `
|
|
215
|
+
- name: Check docs freshness
|
|
216
|
+
run: npx @dommaker/harness sync-docs --check
|
|
217
|
+
continue-on-error: true`
|
|
218
|
+
: '';
|
|
219
|
+
|
|
220
|
+
return `name: Harness Governance
|
|
221
|
+
|
|
222
|
+
on:
|
|
223
|
+
push:
|
|
224
|
+
branches: [main, master]
|
|
225
|
+
pull_request:
|
|
226
|
+
branches: [main, master]
|
|
227
|
+
|
|
228
|
+
jobs:
|
|
229
|
+
governance:
|
|
230
|
+
runs-on: ubuntu-latest
|
|
231
|
+
|
|
232
|
+
steps:
|
|
233
|
+
- uses: actions/checkout@v4
|
|
234
|
+
|
|
235
|
+
- name: Setup Node.js
|
|
236
|
+
uses: actions/setup-node@v4
|
|
237
|
+
with:
|
|
238
|
+
node-version: '20'
|
|
239
|
+
|
|
240
|
+
- name: Install dependencies
|
|
241
|
+
run: npm ci
|
|
242
|
+
|
|
243
|
+
- name: Constraint check
|
|
244
|
+
run: npx @dommaker/harness check
|
|
245
|
+
|
|
246
|
+
- name: Quality gate
|
|
247
|
+
run: npx @dommaker/harness passes-gate
|
|
248
|
+
${docsCheckStep}
|
|
249
|
+
`;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** custom-constraints.yml 示例正文 */
|
|
253
|
+
export const CUSTOM_CONSTRAINTS_TEMPLATE = `# 自定义约束配置
|
|
254
|
+
#
|
|
255
|
+
# 此文件定义项目特定的约束,扩展或覆盖 harness 内置约束
|
|
256
|
+
|
|
257
|
+
# ========================================
|
|
258
|
+
# 自定义约束示例
|
|
259
|
+
# ========================================
|
|
260
|
+
|
|
261
|
+
custom_constraints:
|
|
262
|
+
# 示例 1:禁止 console.log
|
|
263
|
+
# my_project_no_console_log:
|
|
264
|
+
# id: my_project_no_console_log
|
|
265
|
+
# level: guideline
|
|
266
|
+
# rule: "NO CONSOLE.LOG IN PRODUCTION CODE"
|
|
267
|
+
# message: "生产代码禁止使用 console.log,请使用 logger 模块"
|
|
268
|
+
# trigger: ["code_implementation"]
|
|
269
|
+
# description: "使用项目统一的 logger 模块代替 console.log"
|
|
270
|
+
|
|
271
|
+
# 示例 2:禁止特定的导入
|
|
272
|
+
# my_project_no_moment_js:
|
|
273
|
+
# id: my_project_no_moment_js
|
|
274
|
+
# level: guideline
|
|
275
|
+
# rule: "NO MOMENT.JS IMPORTS"
|
|
276
|
+
# message: "禁止使用 moment.js,请使用 date-fns 或 dayjs"
|
|
277
|
+
# trigger: ["code_implementation"]
|
|
278
|
+
|
|
279
|
+
# 示例 3:要求特定的文件命名
|
|
280
|
+
# my_project_component_naming:
|
|
281
|
+
# id: my_project_component_naming
|
|
282
|
+
# level: tip
|
|
283
|
+
# rule: "REACT COMPONENTS SHOULD BE PASCAL CASE"
|
|
284
|
+
# message: "React 组件文件名应使用 PascalCase"
|
|
285
|
+
# trigger: ["file_creation"]
|
|
286
|
+
`;
|
|
287
|
+
|
|
288
|
+
/** CHANGELOG.md 正文(`format` 来自治理配置的 changelog.format) */
|
|
289
|
+
export function renderChangelog(format: string): string {
|
|
290
|
+
return format === 'keep-a-changelog'
|
|
291
|
+
? `# Changelog
|
|
292
|
+
|
|
293
|
+
All notable changes to this project will be documented in this file.
|
|
294
|
+
|
|
295
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
296
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
297
|
+
|
|
298
|
+
## [Unreleased]
|
|
299
|
+
|
|
300
|
+
### Added
|
|
301
|
+
- Initial project setup with harness governance
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
> 此文件可由 \`harness sync-docs\` 辅助维护
|
|
306
|
+
`
|
|
307
|
+
: `# Changelog
|
|
308
|
+
|
|
309
|
+
## [Unreleased]
|
|
310
|
+
|
|
311
|
+
- Initial project setup with harness governance
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
> 此文件可由 \`harness sync-docs\` 辅助维护
|
|
316
|
+
`;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/** 目录 CONTEXT.md 骨架正文(`dir` 是相对项目根的目录路径) */
|
|
320
|
+
export function renderContextDoc(dir: string): string {
|
|
321
|
+
const dirName = path.basename(dir);
|
|
322
|
+
return `# ${dirName}
|
|
323
|
+
|
|
324
|
+
> 此文件描述 ${dir} 目录的职责和上下文
|
|
325
|
+
> 请阅读本目录的源代码,然后填写以下各节。
|
|
326
|
+
> 如果使用 AI 编码助手,将本文件内容作为 prompt 请求它分析并填写。
|
|
327
|
+
|
|
328
|
+
## 职责
|
|
329
|
+
|
|
330
|
+
<!-- 本目录的核心职责是什么 -->
|
|
331
|
+
|
|
332
|
+
## 核心导出
|
|
333
|
+
|
|
334
|
+
<!-- 本目录对外暴露的主要模块/函数 -->
|
|
335
|
+
|
|
336
|
+
## 依赖关系
|
|
337
|
+
|
|
338
|
+
<!-- 本目录依赖哪些其他模块,谁依赖本目录 -->
|
|
339
|
+
|
|
340
|
+
## 注意事项
|
|
341
|
+
|
|
342
|
+
<!-- 开发时需要注意的约束或约定 -->
|
|
343
|
+
`;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* 默认检查点列表
|
|
348
|
+
*
|
|
349
|
+
* 注:no-console 检查点已移除(工单 23/24)——CLI 产品 src/ 必然有合法 console 输出,
|
|
350
|
+
* 且旧配置 expected:'' 语义恒错;output_* 族修复为真正执行 config.command 后该检查会恒失败。
|
|
351
|
+
*/
|
|
352
|
+
export const DEFAULT_CHECKPOINTS: Checkpoint[] = [
|
|
353
|
+
{
|
|
354
|
+
id: 'build-success',
|
|
355
|
+
name: '构建成功',
|
|
356
|
+
checks: [
|
|
357
|
+
{
|
|
358
|
+
id: 'build-command',
|
|
359
|
+
type: 'command_success',
|
|
360
|
+
config: { command: 'npm run build' },
|
|
361
|
+
message: '构建命令必须成功执行',
|
|
362
|
+
},
|
|
363
|
+
],
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
id: 'test-pass',
|
|
367
|
+
name: '测试通过',
|
|
368
|
+
checks: [
|
|
369
|
+
{
|
|
370
|
+
id: 'test-command',
|
|
371
|
+
type: 'command_success',
|
|
372
|
+
config: { command: 'npm test' },
|
|
373
|
+
message: '测试命令必须成功执行',
|
|
374
|
+
},
|
|
375
|
+
],
|
|
376
|
+
},
|
|
377
|
+
];
|
|
378
|
+
|
|
379
|
+
/** 检查点文件的相对路径约定(validate 的缺省读取面与 init 的落盘面同一处) */
|
|
380
|
+
export const DEFAULT_CHECKPOINT_FILE = '.harness/checkpoints.yml';
|
|
381
|
+
|
|
382
|
+
/** checkpoints.yml 正文 */
|
|
383
|
+
export function renderCheckpoints(): string {
|
|
384
|
+
return yaml.dump({ checkpoints: DEFAULT_CHECKPOINTS }, { indent: 2 });
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/** 默认 Resolutions(RKB — 约束 → 已知解法映射) */
|
|
388
|
+
const DEFAULT_RESOLUTIONS = {
|
|
389
|
+
no_fuzzy_completion_claim: {
|
|
390
|
+
title: 'commit message 缺少验证证据',
|
|
391
|
+
fix: '在 commit message body 中附上验证输出:\n`npx @dommaker/harness check --staged` | `npx @dommaker/harness validate` | `npm test -- --coverage`\n确认全部通过后重新 commit。',
|
|
392
|
+
},
|
|
393
|
+
capability_sync: {
|
|
394
|
+
title: '缺少 CAPABILITIES.md',
|
|
395
|
+
fix: '在项目根目录创建 CAPABILITIES.md,列出所有模块能力清单。运行 `npx @dommaker/harness sync-docs` 可自动生成模板。',
|
|
396
|
+
},
|
|
397
|
+
context_doc_sync: {
|
|
398
|
+
title: '关键目录缺少 CONTEXT.md',
|
|
399
|
+
fix: '在 required_dirs 目录下创建 CONTEXT.md。运行 `npx @dommaker/harness sync-docs` 可自动生成模板。',
|
|
400
|
+
},
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
/** resolutions.json 正文 */
|
|
404
|
+
export function renderResolutions(): string {
|
|
405
|
+
return JSON.stringify(DEFAULT_RESOLUTIONS, null, 2);
|
|
406
|
+
}
|