@dommaker/harness 1.7.0 → 1.8.1
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 +44 -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 +19 -3
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +36 -22
- 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/status.d.ts +8 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +5 -7
- package/dist/cli/commands/status.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/cli/state-io.d.ts +34 -0
- package/dist/cli/state-io.d.ts.map +1 -0
- package/dist/cli/state-io.js +71 -0
- package/dist/cli/state-io.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 +1 -0
- 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/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 +19 -1
- package/dist/hooks/pipeline.d.ts.map +1 -1
- package/dist/hooks/pipeline.js +42 -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 +25 -7
- package/dist/hooks/types.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- 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/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 +0 -1
- package/src/__tests__/public-type-surface.test.ts +5 -4
- 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/__tests__/state-io.test.ts +50 -0
- package/src/cli/commands/CONTEXT.md +30 -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 +170 -0
- package/src/cli/commands/__tests__/check-skip-output.test.ts +4 -1
- package/src/cli/commands/__tests__/check.test.ts +63 -44
- 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__/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__/status-extra.test.ts +25 -8
- package/src/cli/commands/__tests__/status.test.ts +46 -18
- 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 +60 -35
- 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/status.ts +12 -7
- 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/cli/state-io.ts +53 -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 -0
- 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/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 +133 -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 +51 -6
- package/src/hooks/registry.ts +31 -12
- package/src/hooks/types.ts +26 -7
- package/src/index.ts +1 -2
- 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/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
package/src/gates/command.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* 检查命令是否安全,防止执行危险操作
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { gateResult } from './types';
|
|
9
9
|
import type { GateResult, CommandGateConfig, CommandBlacklistRule, Gate, GateContext, GateDecision } from './types';
|
|
10
10
|
import { decisionFromResult } from './decision';
|
|
11
11
|
|
|
@@ -194,6 +194,17 @@ export const DEFAULT_COMMAND_BLACKLIST: CommandBlacklistRule[] = [
|
|
|
194
194
|
},
|
|
195
195
|
];
|
|
196
196
|
|
|
197
|
+
/**
|
|
198
|
+
* 三投影共用的裁决(模块内类型,不入公共面)
|
|
199
|
+
*/
|
|
200
|
+
interface CommandVerdict {
|
|
201
|
+
allowed: boolean;
|
|
202
|
+
blocked: CommandBlacklistRule[];
|
|
203
|
+
warnings: CommandBlacklistRule[];
|
|
204
|
+
audits: CommandBlacklistRule[];
|
|
205
|
+
riskLevel: 'high' | 'medium' | 'low';
|
|
206
|
+
}
|
|
207
|
+
|
|
197
208
|
/**
|
|
198
209
|
* 命令门禁
|
|
199
210
|
*/
|
|
@@ -205,17 +216,10 @@ export class CommandGate implements Gate {
|
|
|
205
216
|
|
|
206
217
|
constructor(config: Partial<CommandGateConfig> = {}) {
|
|
207
218
|
this.config = {
|
|
208
|
-
enabled: config.enabled ?? true,
|
|
209
|
-
strict: config.strict ?? false,
|
|
210
|
-
customBlacklist: config.customBlacklist ?? [],
|
|
211
219
|
ignoreCategories: config.ignoreCategories ?? [],
|
|
212
220
|
};
|
|
213
221
|
|
|
214
|
-
|
|
215
|
-
this.blacklist = [
|
|
216
|
-
...DEFAULT_COMMAND_BLACKLIST,
|
|
217
|
-
...this.config.customBlacklist,
|
|
218
|
-
];
|
|
222
|
+
this.blacklist = [...DEFAULT_COMMAND_BLACKLIST];
|
|
219
223
|
}
|
|
220
224
|
|
|
221
225
|
/**
|
|
@@ -232,40 +236,30 @@ export class CommandGate implements Gate {
|
|
|
232
236
|
async check(command: string): Promise<GateResult> {
|
|
233
237
|
const startTime = Date.now();
|
|
234
238
|
|
|
235
|
-
|
|
236
|
-
return pass('command', '命令门禁已禁用', startTime);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const result = this.checkBlacklist(command);
|
|
239
|
+
const verdict = this.judge(command);
|
|
240
240
|
|
|
241
241
|
return gateResult(
|
|
242
242
|
'command',
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
? this.formatSuccessMessage(
|
|
246
|
-
: this.formatBlockMessage(
|
|
243
|
+
verdict.allowed,
|
|
244
|
+
verdict.allowed
|
|
245
|
+
? this.formatSuccessMessage(verdict)
|
|
246
|
+
: this.formatBlockMessage(verdict),
|
|
247
247
|
startTime,
|
|
248
248
|
{
|
|
249
|
-
blocked:
|
|
250
|
-
warnings:
|
|
251
|
-
audits:
|
|
249
|
+
blocked: verdict.blocked,
|
|
250
|
+
warnings: verdict.warnings,
|
|
251
|
+
audits: verdict.audits,
|
|
252
252
|
command,
|
|
253
253
|
}
|
|
254
254
|
);
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
/**
|
|
258
|
-
*
|
|
258
|
+
* 唯一匹配谓词(#135):类别忽略与规则模式测试只在此处发生。
|
|
259
|
+
* 三个入口一律经 judge() 取它的投影,不再各写一遍匹配循环。
|
|
259
260
|
*/
|
|
260
|
-
private
|
|
261
|
-
|
|
262
|
-
blocked: CommandBlacklistRule[];
|
|
263
|
-
warnings: CommandBlacklistRule[];
|
|
264
|
-
audits: CommandBlacklistRule[];
|
|
265
|
-
} {
|
|
266
|
-
const blocked: CommandBlacklistRule[] = [];
|
|
267
|
-
const warnings: CommandBlacklistRule[] = [];
|
|
268
|
-
const audits: CommandBlacklistRule[] = [];
|
|
261
|
+
private matchCommand(command: string): CommandBlacklistRule[] {
|
|
262
|
+
const hits: CommandBlacklistRule[] = [];
|
|
269
263
|
|
|
270
264
|
for (const rule of this.blacklist) {
|
|
271
265
|
// 跳过忽略的类别
|
|
@@ -274,25 +268,36 @@ export class CommandGate implements Gate {
|
|
|
274
268
|
}
|
|
275
269
|
|
|
276
270
|
if (rule.pattern.test(command)) {
|
|
277
|
-
|
|
278
|
-
case 'block':
|
|
279
|
-
blocked.push(rule);
|
|
280
|
-
break;
|
|
281
|
-
case 'warn':
|
|
282
|
-
warnings.push(rule);
|
|
283
|
-
break;
|
|
284
|
-
case 'audit':
|
|
285
|
-
audits.push(rule);
|
|
286
|
-
break;
|
|
287
|
-
}
|
|
271
|
+
hits.push(rule);
|
|
288
272
|
}
|
|
289
273
|
}
|
|
290
274
|
|
|
275
|
+
return hits;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* 命中集合 → 裁决:级别(block/warn/audit)语义只在此处解释一次,
|
|
280
|
+
* 三投影因此对同一输入不可能互相矛盾。
|
|
281
|
+
*/
|
|
282
|
+
private judge(command: string): CommandVerdict {
|
|
283
|
+
const hits = this.matchCommand(command);
|
|
284
|
+
const blocked = hits.filter(rule => rule.level === 'block');
|
|
285
|
+
const warnings = hits.filter(rule => rule.level === 'warn');
|
|
286
|
+
const audits = hits.filter(rule => rule.level === 'audit');
|
|
287
|
+
|
|
288
|
+
let riskLevel: 'high' | 'medium' | 'low' = 'low';
|
|
289
|
+
if (blocked.length > 0) {
|
|
290
|
+
riskLevel = 'high';
|
|
291
|
+
} else if (warnings.length > 0) {
|
|
292
|
+
riskLevel = 'medium';
|
|
293
|
+
}
|
|
294
|
+
|
|
291
295
|
return {
|
|
292
296
|
allowed: blocked.length === 0,
|
|
293
297
|
blocked,
|
|
294
298
|
warnings,
|
|
295
299
|
audits,
|
|
300
|
+
riskLevel,
|
|
296
301
|
};
|
|
297
302
|
}
|
|
298
303
|
|
|
@@ -335,45 +340,17 @@ export class CommandGate implements Gate {
|
|
|
335
340
|
}
|
|
336
341
|
|
|
337
342
|
/**
|
|
338
|
-
* 快速检查(不生成完整 GateResult
|
|
343
|
+
* 快速检查(不生成完整 GateResult)——谓词裁决的布尔投影,hook 侧入口
|
|
339
344
|
*/
|
|
340
345
|
isAllowed(command: string): boolean {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
for (const rule of this.blacklist) {
|
|
344
|
-
if (this.config.ignoreCategories.includes(rule.category)) {
|
|
345
|
-
continue;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
if (rule.level === 'block' && rule.pattern.test(command)) {
|
|
349
|
-
return false;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
return true;
|
|
346
|
+
return this.judge(command).allowed;
|
|
354
347
|
}
|
|
355
348
|
|
|
356
349
|
/**
|
|
357
|
-
*
|
|
350
|
+
* 获取命令风险等级——谓词裁决的等级投影:命中集合里的最高档
|
|
358
351
|
*/
|
|
359
352
|
getRiskLevel(command: string): 'high' | 'medium' | 'low' {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
for (const rule of this.blacklist) {
|
|
363
|
-
if (this.config.ignoreCategories.includes(rule.category)) {
|
|
364
|
-
continue;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
if (rule.pattern.test(command)) {
|
|
368
|
-
switch (rule.level) {
|
|
369
|
-
case 'block': return 'high';
|
|
370
|
-
case 'warn': return 'medium';
|
|
371
|
-
case 'audit': return 'low';
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
return 'low';
|
|
353
|
+
return this.judge(command).riskLevel;
|
|
377
354
|
}
|
|
378
355
|
|
|
379
356
|
/**
|
package/src/gates/contract.ts
CHANGED
|
@@ -23,7 +23,6 @@ export class ContractGate implements Gate {
|
|
|
23
23
|
|
|
24
24
|
constructor(config: Partial<ContractGateConfig> = {}) {
|
|
25
25
|
this.config = {
|
|
26
|
-
enabled: config.enabled ?? true,
|
|
27
26
|
strict: config.strict ?? true,
|
|
28
27
|
allowBreakingChanges: config.allowBreakingChanges ?? false,
|
|
29
28
|
contractPath: config.contractPath ?? 'openapi.yaml',
|
|
@@ -43,10 +42,6 @@ export class ContractGate implements Gate {
|
|
|
43
42
|
async check(context: GateContext): Promise<GateResult> {
|
|
44
43
|
const startTime = Date.now();
|
|
45
44
|
|
|
46
|
-
if (!this.config.enabled) {
|
|
47
|
-
return pass('contract', '契约门禁已禁用', startTime);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
45
|
try {
|
|
51
46
|
const contractPath = context.newContractPath ??
|
|
52
47
|
path.join(context.projectPath, this.config.contractPath);
|
package/src/gates/definitions.ts
CHANGED
|
@@ -11,10 +11,12 @@
|
|
|
11
11
|
* bareRunsAction:true(无位置参数时跑默认 action 而非显示帮助)。
|
|
12
12
|
* - 本模块禁止 import 任何门禁/命令实现(仅 type import,运行时零依赖)——
|
|
13
13
|
* bin 启动期只加载本纯数据模块(保持 --help/--version 懒加载,
|
|
14
|
-
* 闭环校验在 registry
|
|
14
|
+
* 闭环校验在 registry 加载期执行)。唯一例外 import:`utils/numeric-flag`
|
|
15
|
+
* 纯函数解析器(harness#154 口径条目指名的数值旗帜唯一解析器)。
|
|
15
16
|
*/
|
|
16
17
|
|
|
17
18
|
import type { CommandDefinition } from '../cli/commands/definitions';
|
|
19
|
+
import { requireNumericFlag } from '../utils/numeric-flag';
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* 门禁定义
|
|
@@ -70,7 +72,6 @@ export const GATE_DEFINITIONS: GateDefinition[] = [
|
|
|
70
72
|
{ flags: '-l, --level', description: '显示风险等级' },
|
|
71
73
|
{ flags: '--list', description: '列出所有黑名单规则' },
|
|
72
74
|
{ flags: '--json', description: 'JSON 格式输出' },
|
|
73
|
-
{ flags: '--strict', description: '严格模式(warn 也阻止)' },
|
|
74
75
|
],
|
|
75
76
|
action: { module: 'command', export: 'executeCommand' },
|
|
76
77
|
mapActionArgs: (positionals, options) => [positionals[0], options],
|
|
@@ -117,9 +118,9 @@ export const GATE_DEFINITIONS: GateDefinition[] = [
|
|
|
117
118
|
{
|
|
118
119
|
projectPath: options.projectPath,
|
|
119
120
|
coverage: options.coverage,
|
|
120
|
-
coverageThreshold:
|
|
121
|
+
coverageThreshold: requireNumericFlag('--coverage-threshold', options.coverageThreshold as string | undefined, 'int'),
|
|
121
122
|
bundle: options.bundle,
|
|
122
|
-
bundleThreshold:
|
|
123
|
+
bundleThreshold: requireNumericFlag('--bundle-threshold', options.bundleThreshold as string | undefined, 'int'),
|
|
123
124
|
},
|
|
124
125
|
],
|
|
125
126
|
},
|
|
@@ -146,7 +147,7 @@ export const GATE_DEFINITIONS: GateDefinition[] = [
|
|
|
146
147
|
mapActionArgs: (_positionals, options) => [
|
|
147
148
|
{
|
|
148
149
|
projectPath: options.projectPath,
|
|
149
|
-
minReviewers:
|
|
150
|
+
minReviewers: requireNumericFlag('--min-reviewers', options.minReviewers as string | undefined, 'int'),
|
|
150
151
|
requireApproval: options.requireApproval,
|
|
151
152
|
blockOnChangesRequested: options.blockOnChanges,
|
|
152
153
|
allowedReviewers: options.allowedReviewers,
|
package/src/gates/index.ts
CHANGED
|
@@ -47,11 +47,6 @@ export { getGate, listRegisteredGates, registeredGateCount, assertGateRegistryCl
|
|
|
47
47
|
*/
|
|
48
48
|
export { runGates, type GateRunResult } from './runner';
|
|
49
49
|
|
|
50
|
-
/**
|
|
51
|
-
* 生效门禁集:config.yml gates.order / gates.<id>.enabled 声明式裁剪
|
|
52
|
-
*/
|
|
53
|
-
export { getEffectiveGates, type GatesConfig } from './effective-gates';
|
|
54
|
-
|
|
55
50
|
/**
|
|
56
51
|
* checker-as-guard 接线点:ConstraintCheck → Gate(studio #129 随动)
|
|
57
52
|
*/
|
package/src/gates/performance.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import { execAsync } from '../utils/exec';
|
|
19
19
|
import * as fs from 'fs/promises';
|
|
20
20
|
import * as path from 'path';
|
|
21
|
-
import {
|
|
21
|
+
import { gateResult, fromError } from './types';
|
|
22
22
|
import type { GateResult, GateContext, PerformanceGateConfig, PerformanceThresholds, Gate, GateDecision } from './types';
|
|
23
23
|
import { decisionFromResult } from './decision';
|
|
24
24
|
|
|
@@ -45,7 +45,6 @@ export class PerformanceGate implements Gate {
|
|
|
45
45
|
|
|
46
46
|
constructor(config: Partial<ExtendedPerformanceGateConfig> = {}) {
|
|
47
47
|
this.config = {
|
|
48
|
-
enabled: config.enabled ?? true,
|
|
49
48
|
thresholds: config.thresholds ?? {},
|
|
50
49
|
coverageTimeout: config.coverageTimeout ?? DEFAULT_TIMEOUTS.coverage,
|
|
51
50
|
};
|
|
@@ -64,10 +63,6 @@ export class PerformanceGate implements Gate {
|
|
|
64
63
|
async check(context: GateContext): Promise<GateResult> {
|
|
65
64
|
const startTime = Date.now();
|
|
66
65
|
|
|
67
|
-
if (!this.config.enabled) {
|
|
68
|
-
return pass('performance', '性能门禁已禁用', startTime);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
66
|
try {
|
|
72
67
|
const thresholds = context.performanceThresholds ?? this.config.thresholds;
|
|
73
68
|
const metrics = await this.collectMetrics(context.projectPath, thresholds);
|
package/src/gates/runner.ts
CHANGED
package/src/gates/security.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { execAsync } from '../utils/exec';
|
|
11
|
-
import {
|
|
11
|
+
import { gateResult, fromError } from './types';
|
|
12
12
|
import type { GateResult, GateContext, SecurityGateConfig, Gate, GateDecision } from './types';
|
|
13
13
|
import { decisionFromResult } from './decision';
|
|
14
14
|
|
|
@@ -18,12 +18,13 @@ import { decisionFromResult } from './decision';
|
|
|
18
18
|
export class SecurityGate implements Gate {
|
|
19
19
|
readonly id = 'security';
|
|
20
20
|
order = 0;
|
|
21
|
-
private config:
|
|
21
|
+
private config: SecurityGateConfig;
|
|
22
22
|
|
|
23
23
|
constructor(config: Partial<SecurityGateConfig> = {}) {
|
|
24
24
|
this.config = {
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
// 空串归一为 undefined:`?? ''` 曾把「未提供」表示成空串,令下方 `??` 链恒停在
|
|
26
|
+
// 第二级、detectScanCommand() 不可达(#138)。「未提供」的唯一表示是 undefined。
|
|
27
|
+
scanCommand: config.scanCommand || undefined,
|
|
27
28
|
ignoreWarnings: config.ignoreWarnings ?? false,
|
|
28
29
|
ignoreDevDependencies: config.ignoreDevDependencies ?? false,
|
|
29
30
|
severityThreshold: config.severityThreshold ?? 'high',
|
|
@@ -43,13 +44,10 @@ export class SecurityGate implements Gate {
|
|
|
43
44
|
async scan(context: GateContext): Promise<GateResult> {
|
|
44
45
|
const startTime = Date.now();
|
|
45
46
|
|
|
46
|
-
if (!this.config.enabled) {
|
|
47
|
-
return pass('security', '安全门禁已禁用', startTime);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
47
|
try {
|
|
51
|
-
//
|
|
52
|
-
|
|
48
|
+
// 三级优先级(自上而下取第一个「已提供」者):context 覆盖 > 构造配置 > 自动探测。
|
|
49
|
+
// 缺省(未给命令)落到 detectScanCommand()——本行曾因构造器兜空串而恒停在第二级(#138)。
|
|
50
|
+
const scanCommand = context.securityScanCommand ??
|
|
53
51
|
this.config.scanCommand ??
|
|
54
52
|
this.detectScanCommand(context.projectPath);
|
|
55
53
|
|
|
@@ -234,7 +232,7 @@ export class SecurityGate implements Gate {
|
|
|
234
232
|
/**
|
|
235
233
|
* 获取配置
|
|
236
234
|
*/
|
|
237
|
-
getConfig():
|
|
235
|
+
getConfig(): SecurityGateConfig {
|
|
238
236
|
return { ...this.config };
|
|
239
237
|
}
|
|
240
238
|
}
|
package/src/gates/types.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* 门禁类型定义 + GateResult 构造器
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import type { RunEnv } from '../core/constraints/run-env';
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
8
|
* 门禁结果(报告结构,保留)
|
|
7
9
|
*
|
|
@@ -115,38 +117,39 @@ export interface Gate {
|
|
|
115
117
|
}
|
|
116
118
|
|
|
117
119
|
/**
|
|
118
|
-
*
|
|
120
|
+
* 门禁上下文:只带「这次在哪跑、跑什么」这类运行信息
|
|
121
|
+
*
|
|
122
|
+
* 配置一律走构造器(`ReviewGateConfig` 等),不要往这里加字段——
|
|
123
|
+
* 本类型曾有 6 个无人读取的配置型字段与构造器配置平行,填了不生效。
|
|
119
124
|
*/
|
|
120
125
|
export interface GateContext {
|
|
121
|
-
projectId: string;
|
|
122
|
-
taskId?: string;
|
|
123
126
|
projectPath: string;
|
|
124
|
-
|
|
127
|
+
taskId?: string;
|
|
128
|
+
|
|
125
129
|
// Review Gate
|
|
126
130
|
prNumber?: number;
|
|
127
|
-
|
|
128
|
-
reviewers?: string[];
|
|
129
|
-
|
|
131
|
+
|
|
130
132
|
// Security Gate
|
|
131
133
|
securityScanCommand?: string;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
+
|
|
134
135
|
// Performance Gate
|
|
135
136
|
performanceThresholds?: PerformanceThresholds;
|
|
136
|
-
|
|
137
|
+
|
|
137
138
|
// Contract Gate
|
|
138
139
|
oldContractPath?: string;
|
|
139
140
|
newContractPath?: string;
|
|
140
|
-
openApiSpec?: string;
|
|
141
141
|
|
|
142
142
|
// Command Gate
|
|
143
143
|
command?: string;
|
|
144
144
|
|
|
145
145
|
// Acceptance Gate
|
|
146
146
|
tasksPath?: string;
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* 本 run 的运行级观察面(ADR-0023)。一条守卫链传同一枚 → 项目配置文件整链至多读一次;
|
|
150
|
+
* 不传 = 各门禁自造一枚一次性观察面(判定不变,只是不共享读取)
|
|
151
|
+
*/
|
|
152
|
+
runEnv?: RunEnv;
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
/**
|
|
@@ -172,7 +175,6 @@ export interface ReviewGateConfig {
|
|
|
172
175
|
* 安全门禁配置
|
|
173
176
|
*/
|
|
174
177
|
export interface SecurityGateConfig {
|
|
175
|
-
enabled: boolean;
|
|
176
178
|
scanCommand?: string;
|
|
177
179
|
ignoreWarnings: boolean;
|
|
178
180
|
ignoreDevDependencies: boolean;
|
|
@@ -183,7 +185,6 @@ export interface SecurityGateConfig {
|
|
|
183
185
|
* 性能门禁配置
|
|
184
186
|
*/
|
|
185
187
|
export interface PerformanceGateConfig {
|
|
186
|
-
enabled: boolean;
|
|
187
188
|
thresholds: PerformanceThresholds;
|
|
188
189
|
}
|
|
189
190
|
|
|
@@ -191,7 +192,6 @@ export interface PerformanceGateConfig {
|
|
|
191
192
|
* 契约门禁配置
|
|
192
193
|
*/
|
|
193
194
|
export interface ContractGateConfig {
|
|
194
|
-
enabled: boolean;
|
|
195
195
|
strict: boolean;
|
|
196
196
|
allowBreakingChanges: boolean;
|
|
197
197
|
contractPath?: string;
|
|
@@ -252,14 +252,11 @@ export interface CommandBlacklistRule {
|
|
|
252
252
|
|
|
253
253
|
/**
|
|
254
254
|
* 命令门禁配置
|
|
255
|
+
*
|
|
256
|
+
* `strict`(从不被判定读取)与 `customBlacklist`(零生产注入者,运行时扩展点是
|
|
257
|
+
* `CommandGate.addRule()`)两个配置位已删除,裁决见 ADR-0024(#135)。
|
|
255
258
|
*/
|
|
256
259
|
export interface CommandGateConfig {
|
|
257
|
-
/** 是否启用 */
|
|
258
|
-
enabled?: boolean;
|
|
259
|
-
/** 严格模式(warn 也阻止) */
|
|
260
|
-
strict?: boolean;
|
|
261
|
-
/** 自定义黑名单规则 */
|
|
262
|
-
customBlacklist?: CommandBlacklistRule[];
|
|
263
260
|
/** 忽略的类别 */
|
|
264
261
|
ignoreCategories?: string[];
|
|
265
262
|
}
|
package/src/hooks/CONTEXT.md
CHANGED
|
@@ -5,26 +5,27 @@
|
|
|
5
5
|
|
|
6
6
|
H5(#44)起增加两个机制(G2/G7):
|
|
7
7
|
- **注册表闭环**:`assertHookRegistryClosed(configs, hooks)` 声明(HookConfig)↔ 实现(HookDefinition)双向校验——引用未注册/注册无定义/重复均抛错,复制 checker 闭环模式;断言限构建/测试期,不进运行时热路径
|
|
8
|
-
- **配置归一**:`HookConfig { name, enabled, errorStrategy }` 为 per-hook
|
|
8
|
+
- **配置归一**:`HookConfig { name, enabled, errorStrategy }` 为 per-hook 配置唯一真相,且自 #159 起是 `enabled` / `errorStrategy` 的**唯一声明点**——`HookDefinition` 不再携带这两个字段,注册环节以配置表填充有效值(`EffectiveHook`),声明一处、读取一处,两侧矛盾在构造上不可能出现;`toErrorStrategy(blocking)` 承载 studio `blocking` → errorStrategy 的无损映射
|
|
9
9
|
|
|
10
10
|
## 核心导出
|
|
11
|
-
- `HookRegistry` — Hook 注册表(register/get/getEnabled/setEnabled/clear
|
|
12
|
-
- `HookPipeline` — Hook 执行管线(注册/排序/错误隔离/采样;errorStrategy block/warn/
|
|
11
|
+
- `HookRegistry` — Hook 注册表(register/registerAll/unregister/get/getEnabled/listNames/listAll/setEnabled/clear;register 以 HookConfig 填充有效值)
|
|
12
|
+
- `HookPipeline` — Hook 执行管线(注册/排序/错误隔离/采样;errorStrategy block/warn;`run(phase)` 时机粒度、`runFull` 全套、`runOne(name)` 按名执行单个 hook——#167 新增:enabled:false 返回 skipped:true 记录且实现体零调用,block 失败抛错 / warn 失败返回 passed:false 记录,未知名抛错(口径同注册表闭环),采样与错误隔离复用 executeOne 单路径)
|
|
13
13
|
- `assertHookRegistryClosed` — 注册表闭环双向校验(构建/测试期)
|
|
14
|
-
- `HookConfig`(type)— per-hook
|
|
14
|
+
- `HookConfig`(type)— per-hook 配置声明(enabled / errorStrategy 唯一声明点)
|
|
15
|
+
- `EffectiveHook`(type)— HookDefinition + 配置填充的有效 enabled / errorStrategy(管线与注册表判定只读它)
|
|
15
16
|
- `toErrorStrategy` — blocking → errorStrategy 无损映射(G7)
|
|
16
|
-
- `bootstrapHarness` / `bootstrapHarnessSync` — Harness 启动引导;也是 trace 记录器的组合根:`new ConstraintChecker(
|
|
17
|
+
- `bootstrapHarness` / `bootstrapHarnessSync` — Harness 启动引导;也是 trace 记录器的组合根:`new ConstraintChecker(new TraceCollector({ projectPath }))`(harness#88 接线,core 不上行依赖 monitoring,故由本层接线;#139 收根:两个入口本就收 projectPath,落点随之锚定,不再取 cwd 锚定的 `getTraceCollector()` 单例)
|
|
17
18
|
|
|
18
19
|
## 依赖关系
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
20
|
+
- 类型正本在**本模块** `src/hooks/types.ts`(`HookPhase`/`HookErrorStrategy`/`HookConfig`/`HookDefinition`/`EffectiveHook`/`HookResult`/`PipelineResult`);`src/types/` 里没有 hook 类型,本层只从 `src/types/project-config` 取 `MergedConstraintsConfig` 类型
|
|
21
|
+
- 向下依赖(仅 `bootstrap.ts` 组合根):`core/constraints/checker`、`core/project-config-loader`、`context/session-manager`、`monitoring/traces`——`registry/pipeline/config/types` 四文件零上层依赖,是纯管线
|
|
22
|
+
- 消费方:包根 `src/index.ts` 的 `./hooks` 出口与下游项目(studio 的 hook 装配)。**harness 内部无生产消费方**——core/cli 侧的调用边已随零消费者清账删除(harness#141 同判据,ADR-0022),「被 core 核心引擎/CLI 初始化流程消费」的旧说法已失效(harness#142 核对)
|
|
22
23
|
|
|
23
24
|
## 约定
|
|
24
25
|
- 无业务逻辑,只提供管线能力
|
|
25
26
|
- Consumer 自行定义 hook 名称和触发时机
|
|
26
27
|
- **闭环**:声明配置与注册实现必须一一对应,缺一抛错(消灭「hook 定义不注册 = 死代码」类人记规矩)
|
|
27
|
-
- **映射语义**:blocking=true → 'block'(失败阻断管线,停止后续 hook、passed=false);blocking=false → 'warn'
|
|
28
|
+
- **映射语义**:blocking=true → 'block'(失败阻断管线,停止后续 hook、passed=false);blocking=false → 'warn'(记录警告继续);有效策略集合仅 'block' | 'warn'(#159 起原 'ignore' 与「未声明 strategy」形态退出有效面——策略由 HookConfig 必填声明)
|
|
28
29
|
- 错误隔离:单个 hook 失败不影响其他 hook
|
|
29
30
|
|
|
30
31
|
## 注意事项
|
|
@@ -11,7 +11,11 @@ import * as fs from 'fs';
|
|
|
11
11
|
import * as path from 'path';
|
|
12
12
|
import * as yaml from 'js-yaml';
|
|
13
13
|
import { bootstrapHarnessSync, bootstrapHarness } from '../bootstrap';
|
|
14
|
-
import type { HookDefinition } from '../types';
|
|
14
|
+
import type { HookConfig, HookDefinition } from '../types';
|
|
15
|
+
|
|
16
|
+
function makeHookConfig(name: string, overrides: Partial<HookConfig> = {}): HookConfig {
|
|
17
|
+
return { name, enabled: true, errorStrategy: 'warn', ...overrides };
|
|
18
|
+
}
|
|
15
19
|
|
|
16
20
|
function setupTempDir(dir: string): string {
|
|
17
21
|
const harnessDir = path.join(dir, '.harness');
|
|
@@ -51,14 +55,24 @@ describe('bootstrapHarness', () => {
|
|
|
51
55
|
expect(result.projectPath).toBe(tempDir);
|
|
52
56
|
});
|
|
53
57
|
|
|
54
|
-
it('registers hook definitions when provided', async () => {
|
|
58
|
+
it('registers hook definitions when provided (with configs)', async () => {
|
|
55
59
|
const hookDef: HookDefinition = {
|
|
56
60
|
name: 'async-hook',
|
|
57
61
|
phase: 'before',
|
|
58
62
|
execute: async () => ({ passed: true }),
|
|
59
63
|
};
|
|
60
|
-
const result = await bootstrapHarness(tempDir, [hookDef]);
|
|
64
|
+
const result = await bootstrapHarness(tempDir, [hookDef], [makeHookConfig('async-hook')]);
|
|
61
65
|
expect(result.hooks.listNames()).toContain('async-hook');
|
|
66
|
+
expect(result.hooks.get('async-hook')?.errorStrategy).toBe('warn');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('throws when definitions are provided without configs (#159)', async () => {
|
|
70
|
+
const hookDef: HookDefinition = {
|
|
71
|
+
name: 'async-hook',
|
|
72
|
+
phase: 'before',
|
|
73
|
+
execute: async () => ({ passed: true }),
|
|
74
|
+
};
|
|
75
|
+
await expect(bootstrapHarness(tempDir, [hookDef])).rejects.toThrow(/HookConfig/);
|
|
62
76
|
});
|
|
63
77
|
|
|
64
78
|
it('does not register hooks when no definitions provided', async () => {
|
|
@@ -126,16 +140,25 @@ describe('bootstrapHarnessSync', () => {
|
|
|
126
140
|
expect(result.mergedConstraints).toHaveProperty('guidelines');
|
|
127
141
|
});
|
|
128
142
|
|
|
129
|
-
it('registers hook definitions when provided', () => {
|
|
143
|
+
it('registers hook definitions when provided (with configs)', () => {
|
|
130
144
|
const hookDef: HookDefinition = {
|
|
131
145
|
name: 'test-hook',
|
|
132
146
|
phase: 'before',
|
|
133
147
|
execute: async () => ({ passed: true }),
|
|
134
148
|
};
|
|
135
|
-
const result = bootstrapHarnessSync(tempDir, [hookDef]);
|
|
149
|
+
const result = bootstrapHarnessSync(tempDir, [hookDef], [makeHookConfig('test-hook')]);
|
|
136
150
|
expect(result.hooks.listNames()).toContain('test-hook');
|
|
137
151
|
});
|
|
138
152
|
|
|
153
|
+
it('throws when definitions are provided without configs (#159)', () => {
|
|
154
|
+
const hookDef: HookDefinition = {
|
|
155
|
+
name: 'test-hook',
|
|
156
|
+
phase: 'before',
|
|
157
|
+
execute: async () => ({ passed: true }),
|
|
158
|
+
};
|
|
159
|
+
expect(() => bootstrapHarnessSync(tempDir, [hookDef])).toThrow(/HookConfig/);
|
|
160
|
+
});
|
|
161
|
+
|
|
139
162
|
it('does not register hooks when no definitions provided', () => {
|
|
140
163
|
const result = bootstrapHarnessSync(tempDir, []);
|
|
141
164
|
expect(result.hooks.listNames()).toEqual([]);
|
|
@@ -165,7 +188,7 @@ describe('bootstrapHarnessSync', () => {
|
|
|
165
188
|
phase: 'after',
|
|
166
189
|
execute: async () => ({ passed: true, data: 'ok' }),
|
|
167
190
|
};
|
|
168
|
-
const result = bootstrapHarnessSync(tempDir, [hookDef]);
|
|
191
|
+
const result = bootstrapHarnessSync(tempDir, [hookDef], [makeHookConfig('pipeline-hook')]);
|
|
169
192
|
expect(result.pipeline).toBeDefined();
|
|
170
193
|
});
|
|
171
194
|
|