@neurcode-ai/cli 0.9.64 → 0.9.66
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/LICENSE +201 -0
- package/dist/commands/bootstrap-policy.d.ts +29 -0
- package/dist/commands/bootstrap-policy.d.ts.map +1 -0
- package/dist/commands/bootstrap-policy.js +334 -0
- package/dist/commands/bootstrap-policy.js.map +1 -0
- package/dist/commands/brain.d.ts.map +1 -1
- package/dist/commands/brain.js +273 -0
- package/dist/commands/brain.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +82 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/pilot-report.d.ts +9 -0
- package/dist/commands/pilot-report.d.ts.map +1 -0
- package/dist/commands/pilot-report.js +176 -0
- package/dist/commands/pilot-report.js.map +1 -0
- package/dist/commands/quickstart.d.ts +21 -0
- package/dist/commands/quickstart.d.ts.map +1 -0
- package/dist/commands/quickstart.js +178 -0
- package/dist/commands/quickstart.js.map +1 -0
- package/dist/commands/remediate-export.d.ts +31 -0
- package/dist/commands/remediate-export.d.ts.map +1 -0
- package/dist/commands/remediate-export.js +283 -0
- package/dist/commands/remediate-export.js.map +1 -0
- package/dist/commands/remediate-governance.d.ts +54 -0
- package/dist/commands/remediate-governance.d.ts.map +1 -0
- package/dist/commands/remediate-governance.js +375 -0
- package/dist/commands/remediate-governance.js.map +1 -0
- package/dist/commands/remediate.d.ts.map +1 -1
- package/dist/commands/remediate.js.map +1 -1
- package/dist/commands/replay.d.ts.map +1 -1
- package/dist/commands/replay.js +30 -0
- package/dist/commands/replay.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +409 -30
- package/dist/commands/verify.js.map +1 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +1078 -0
- package/dist/daemon/server.js.map +1 -1
- package/dist/explainability/DeterminismClassifier.d.ts +34 -0
- package/dist/explainability/DeterminismClassifier.d.ts.map +1 -0
- package/dist/explainability/DeterminismClassifier.js +104 -0
- package/dist/explainability/DeterminismClassifier.js.map +1 -0
- package/dist/explainability/ViolationFormatter.d.ts +32 -0
- package/dist/explainability/ViolationFormatter.d.ts.map +1 -0
- package/dist/explainability/ViolationFormatter.js +252 -0
- package/dist/explainability/ViolationFormatter.js.map +1 -0
- package/dist/explainability/index.d.ts +15 -0
- package/dist/explainability/index.d.ts.map +1 -0
- package/dist/explainability/index.js +94 -0
- package/dist/explainability/index.js.map +1 -0
- package/dist/explainability/types.d.ts +37 -0
- package/dist/explainability/types.d.ts.map +1 -0
- package/dist/explainability/types.js +3 -0
- package/dist/explainability/types.js.map +1 -0
- package/dist/governance/canonical-invariants.d.ts +88 -0
- package/dist/governance/canonical-invariants.d.ts.map +1 -0
- package/dist/governance/canonical-invariants.js +197 -0
- package/dist/governance/canonical-invariants.js.map +1 -0
- package/dist/governance/canonical-ordering.d.ts +76 -0
- package/dist/governance/canonical-ordering.d.ts.map +1 -0
- package/dist/governance/canonical-ordering.js +189 -0
- package/dist/governance/canonical-ordering.js.map +1 -0
- package/dist/governance/canonical-pipeline.d.ts +45 -0
- package/dist/governance/canonical-pipeline.d.ts.map +1 -0
- package/dist/governance/canonical-pipeline.js +616 -0
- package/dist/governance/canonical-pipeline.js.map +1 -0
- package/dist/governance/diff-line-provenance.d.ts +59 -0
- package/dist/governance/diff-line-provenance.d.ts.map +1 -0
- package/dist/governance/diff-line-provenance.js +118 -0
- package/dist/governance/diff-line-provenance.js.map +1 -0
- package/dist/governance/pilot-readiness.d.ts +34 -0
- package/dist/governance/pilot-readiness.d.ts.map +1 -0
- package/dist/governance/pilot-readiness.js +226 -0
- package/dist/governance/pilot-readiness.js.map +1 -0
- package/dist/governance/policy-parity-validator.d.ts +62 -0
- package/dist/governance/policy-parity-validator.d.ts.map +1 -0
- package/dist/governance/policy-parity-validator.js +137 -0
- package/dist/governance/policy-parity-validator.js.map +1 -0
- package/dist/governance/remediation-boundary.d.ts +55 -0
- package/dist/governance/remediation-boundary.d.ts.map +1 -0
- package/dist/governance/remediation-boundary.js +120 -0
- package/dist/governance/remediation-boundary.js.map +1 -0
- package/dist/governance/structural-cache.d.ts +103 -0
- package/dist/governance/structural-cache.d.ts.map +1 -0
- package/dist/governance/structural-cache.js +240 -0
- package/dist/governance/structural-cache.js.map +1 -0
- package/dist/governance/structural-on-diff.d.ts +33 -0
- package/dist/governance/structural-on-diff.d.ts.map +1 -0
- package/dist/governance/structural-on-diff.js +67 -0
- package/dist/governance/structural-on-diff.js.map +1 -0
- package/dist/governance/structural-policy-merge.d.ts +22 -0
- package/dist/governance/structural-policy-merge.d.ts.map +1 -0
- package/dist/governance/structural-policy-merge.js +32 -0
- package/dist/governance/structural-policy-merge.js.map +1 -0
- package/dist/governance/verify-runtime-guard.d.ts +99 -0
- package/dist/governance/verify-runtime-guard.d.ts.map +1 -0
- package/dist/governance/verify-runtime-guard.js +129 -0
- package/dist/governance/verify-runtime-guard.js.map +1 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -1
- package/dist/integrations/review-compression/index.d.ts +50 -0
- package/dist/integrations/review-compression/index.d.ts.map +1 -0
- package/dist/integrations/review-compression/index.js +158 -0
- package/dist/integrations/review-compression/index.js.map +1 -0
- package/dist/intent-engine/domain-taxonomy.d.ts +42 -0
- package/dist/intent-engine/domain-taxonomy.d.ts.map +1 -0
- package/dist/intent-engine/domain-taxonomy.js +534 -0
- package/dist/intent-engine/domain-taxonomy.js.map +1 -0
- package/dist/intent-engine/index.d.ts +1 -0
- package/dist/intent-engine/index.d.ts.map +1 -1
- package/dist/intent-engine/index.js +6 -1
- package/dist/intent-engine/index.js.map +1 -1
- package/dist/intent-engine/parser.d.ts.map +1 -1
- package/dist/intent-engine/parser.js +47 -0
- package/dist/intent-engine/parser.js.map +1 -1
- package/dist/intent-engine/repo-classifier.d.ts +64 -0
- package/dist/intent-engine/repo-classifier.d.ts.map +1 -0
- package/dist/intent-engine/repo-classifier.js +178 -0
- package/dist/intent-engine/repo-classifier.js.map +1 -0
- package/dist/intent-engine/semantic-expander.d.ts +104 -0
- package/dist/intent-engine/semantic-expander.d.ts.map +1 -0
- package/dist/intent-engine/semantic-expander.js +480 -0
- package/dist/intent-engine/semantic-expander.js.map +1 -0
- package/dist/patch-engine/patterns.d.ts.map +1 -1
- package/dist/patch-engine/patterns.js +8 -4
- package/dist/patch-engine/patterns.js.map +1 -1
- package/dist/semantic/index.d.ts +14 -0
- package/dist/semantic/index.d.ts.map +1 -0
- package/dist/semantic/index.js +30 -0
- package/dist/semantic/index.js.map +1 -0
- package/dist/semantic/tfidf-engine.d.ts +81 -0
- package/dist/semantic/tfidf-engine.d.ts.map +1 -0
- package/dist/semantic/tfidf-engine.js +278 -0
- package/dist/semantic/tfidf-engine.js.map +1 -0
- package/dist/semantic/vector-store.d.ts +108 -0
- package/dist/semantic/vector-store.d.ts.map +1 -0
- package/dist/semantic/vector-store.js +321 -0
- package/dist/semantic/vector-store.js.map +1 -0
- package/dist/structural-rules/context-severity.d.ts +46 -0
- package/dist/structural-rules/context-severity.d.ts.map +1 -0
- package/dist/structural-rules/context-severity.js +115 -0
- package/dist/structural-rules/context-severity.js.map +1 -0
- package/dist/structural-rules/distributed/DS001-saga-rollback-absence.d.ts +11 -0
- package/dist/structural-rules/distributed/DS001-saga-rollback-absence.d.ts.map +1 -0
- package/dist/structural-rules/distributed/DS001-saga-rollback-absence.js +212 -0
- package/dist/structural-rules/distributed/DS001-saga-rollback-absence.js.map +1 -0
- package/dist/structural-rules/distributed/DS002-missing-correlation-id.d.ts +11 -0
- package/dist/structural-rules/distributed/DS002-missing-correlation-id.d.ts.map +1 -0
- package/dist/structural-rules/distributed/DS002-missing-correlation-id.js +213 -0
- package/dist/structural-rules/distributed/DS002-missing-correlation-id.js.map +1 -0
- package/dist/structural-rules/distributed/index.d.ts +3 -0
- package/dist/structural-rules/distributed/index.d.ts.map +1 -0
- package/dist/structural-rules/distributed/index.js +8 -0
- package/dist/structural-rules/distributed/index.js.map +1 -0
- package/dist/structural-rules/engine.d.ts +25 -0
- package/dist/structural-rules/engine.d.ts.map +1 -0
- package/dist/structural-rules/engine.js +90 -0
- package/dist/structural-rules/engine.js.map +1 -0
- package/dist/structural-rules/index.d.ts +45 -0
- package/dist/structural-rules/index.d.ts.map +1 -0
- package/dist/structural-rules/index.js +158 -0
- package/dist/structural-rules/index.js.map +1 -0
- package/dist/structural-rules/python/PY001-asyncio-task-without-cancel.d.ts +11 -0
- package/dist/structural-rules/python/PY001-asyncio-task-without-cancel.d.ts.map +1 -0
- package/dist/structural-rules/python/PY001-asyncio-task-without-cancel.js +66 -0
- package/dist/structural-rules/python/PY001-asyncio-task-without-cancel.js.map +1 -0
- package/dist/structural-rules/python/PY002-unbounded-dict-singleton.d.ts +11 -0
- package/dist/structural-rules/python/PY002-unbounded-dict-singleton.d.ts.map +1 -0
- package/dist/structural-rules/python/PY002-unbounded-dict-singleton.js +135 -0
- package/dist/structural-rules/python/PY002-unbounded-dict-singleton.js.map +1 -0
- package/dist/structural-rules/python/PY003-broad-except-clause.d.ts +32 -0
- package/dist/structural-rules/python/PY003-broad-except-clause.d.ts.map +1 -0
- package/dist/structural-rules/python/PY003-broad-except-clause.js +277 -0
- package/dist/structural-rules/python/PY003-broad-except-clause.js.map +1 -0
- package/dist/structural-rules/python/PY004-swallowed-async-exception.d.ts +11 -0
- package/dist/structural-rules/python/PY004-swallowed-async-exception.d.ts.map +1 -0
- package/dist/structural-rules/python/PY004-swallowed-async-exception.js +167 -0
- package/dist/structural-rules/python/PY004-swallowed-async-exception.js.map +1 -0
- package/dist/structural-rules/python/PY005-fastapi-without-pydantic.d.ts +11 -0
- package/dist/structural-rules/python/PY005-fastapi-without-pydantic.d.ts.map +1 -0
- package/dist/structural-rules/python/PY005-fastapi-without-pydantic.js +154 -0
- package/dist/structural-rules/python/PY005-fastapi-without-pydantic.js.map +1 -0
- package/dist/structural-rules/python/PY006-blocking-io-in-async.d.ts +11 -0
- package/dist/structural-rules/python/PY006-blocking-io-in-async.d.ts.map +1 -0
- package/dist/structural-rules/python/PY006-blocking-io-in-async.js +130 -0
- package/dist/structural-rules/python/PY006-blocking-io-in-async.js.map +1 -0
- package/dist/structural-rules/python/PY007-sqlalchemy-session-leak.d.ts +11 -0
- package/dist/structural-rules/python/PY007-sqlalchemy-session-leak.d.ts.map +1 -0
- package/dist/structural-rules/python/PY007-sqlalchemy-session-leak.js +93 -0
- package/dist/structural-rules/python/PY007-sqlalchemy-session-leak.js.map +1 -0
- package/dist/structural-rules/python/PY008-celery-task-without-retry.d.ts +11 -0
- package/dist/structural-rules/python/PY008-celery-task-without-retry.d.ts.map +1 -0
- package/dist/structural-rules/python/PY008-celery-task-without-retry.js +154 -0
- package/dist/structural-rules/python/PY008-celery-task-without-retry.js.map +1 -0
- package/dist/structural-rules/python/PY009-unsafe-pickle-deserialization.d.ts +11 -0
- package/dist/structural-rules/python/PY009-unsafe-pickle-deserialization.d.ts.map +1 -0
- package/dist/structural-rules/python/PY009-unsafe-pickle-deserialization.js +133 -0
- package/dist/structural-rules/python/PY009-unsafe-pickle-deserialization.js.map +1 -0
- package/dist/structural-rules/python/PY010-leaked-aiohttp-session.d.ts +11 -0
- package/dist/structural-rules/python/PY010-leaked-aiohttp-session.d.ts.map +1 -0
- package/dist/structural-rules/python/PY010-leaked-aiohttp-session.js +80 -0
- package/dist/structural-rules/python/PY010-leaked-aiohttp-session.js.map +1 -0
- package/dist/structural-rules/python/PY011-thread-lifecycle.d.ts +11 -0
- package/dist/structural-rules/python/PY011-thread-lifecycle.d.ts.map +1 -0
- package/dist/structural-rules/python/PY011-thread-lifecycle.js +97 -0
- package/dist/structural-rules/python/PY011-thread-lifecycle.js.map +1 -0
- package/dist/structural-rules/python/PY012-asyncio-run-misuse.d.ts +11 -0
- package/dist/structural-rules/python/PY012-asyncio-run-misuse.d.ts.map +1 -0
- package/dist/structural-rules/python/PY012-asyncio-run-misuse.js +83 -0
- package/dist/structural-rules/python/PY012-asyncio-run-misuse.js.map +1 -0
- package/dist/structural-rules/python/PY013-mutable-default-arg.d.ts +11 -0
- package/dist/structural-rules/python/PY013-mutable-default-arg.d.ts.map +1 -0
- package/dist/structural-rules/python/PY013-mutable-default-arg.js +73 -0
- package/dist/structural-rules/python/PY013-mutable-default-arg.js.map +1 -0
- package/dist/structural-rules/python/PY014-fixed-sleep-retry.d.ts +11 -0
- package/dist/structural-rules/python/PY014-fixed-sleep-retry.d.ts.map +1 -0
- package/dist/structural-rules/python/PY014-fixed-sleep-retry.js +115 -0
- package/dist/structural-rules/python/PY014-fixed-sleep-retry.js.map +1 -0
- package/dist/structural-rules/rules/SR001-swallowed-async-rejection.d.ts +11 -0
- package/dist/structural-rules/rules/SR001-swallowed-async-rejection.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR001-swallowed-async-rejection.js +145 -0
- package/dist/structural-rules/rules/SR001-swallowed-async-rejection.js.map +1 -0
- package/dist/structural-rules/rules/SR002-unbounded-collection.d.ts +11 -0
- package/dist/structural-rules/rules/SR002-unbounded-collection.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR002-unbounded-collection.js +196 -0
- package/dist/structural-rules/rules/SR002-unbounded-collection.js.map +1 -0
- package/dist/structural-rules/rules/SR003-timer-without-cleanup.d.ts +11 -0
- package/dist/structural-rules/rules/SR003-timer-without-cleanup.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR003-timer-without-cleanup.js +148 -0
- package/dist/structural-rules/rules/SR003-timer-without-cleanup.js.map +1 -0
- package/dist/structural-rules/rules/SR004-request-boundary-no-validation.d.ts +11 -0
- package/dist/structural-rules/rules/SR004-request-boundary-no-validation.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR004-request-boundary-no-validation.js +162 -0
- package/dist/structural-rules/rules/SR004-request-boundary-no-validation.js.map +1 -0
- package/dist/structural-rules/rules/SR005-halfopen-probe-gate.d.ts +11 -0
- package/dist/structural-rules/rules/SR005-halfopen-probe-gate.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR005-halfopen-probe-gate.js +150 -0
- package/dist/structural-rules/rules/SR005-halfopen-probe-gate.js.map +1 -0
- package/dist/structural-rules/rules/SR006-fanout-error-sanitization.d.ts +11 -0
- package/dist/structural-rules/rules/SR006-fanout-error-sanitization.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR006-fanout-error-sanitization.js +161 -0
- package/dist/structural-rules/rules/SR006-fanout-error-sanitization.js.map +1 -0
- package/dist/structural-rules/rules/SR007-cross-request-error.d.ts +11 -0
- package/dist/structural-rules/rules/SR007-cross-request-error.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR007-cross-request-error.js +175 -0
- package/dist/structural-rules/rules/SR007-cross-request-error.js.map +1 -0
- package/dist/structural-rules/rules/SR008-background-task-orphan.d.ts +11 -0
- package/dist/structural-rules/rules/SR008-background-task-orphan.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR008-background-task-orphan.js +176 -0
- package/dist/structural-rules/rules/SR008-background-task-orphan.js.map +1 -0
- package/dist/structural-rules/rules/SR009-missing-retry-backoff.d.ts +11 -0
- package/dist/structural-rules/rules/SR009-missing-retry-backoff.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR009-missing-retry-backoff.js +168 -0
- package/dist/structural-rules/rules/SR009-missing-retry-backoff.js.map +1 -0
- package/dist/structural-rules/rules/SR010-retry-storm.d.ts +11 -0
- package/dist/structural-rules/rules/SR010-retry-storm.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR010-retry-storm.js +181 -0
- package/dist/structural-rules/rules/SR010-retry-storm.js.map +1 -0
- package/dist/structural-rules/rules/SR011-event-listener-leak.d.ts +11 -0
- package/dist/structural-rules/rules/SR011-event-listener-leak.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR011-event-listener-leak.js +208 -0
- package/dist/structural-rules/rules/SR011-event-listener-leak.js.map +1 -0
- package/dist/structural-rules/rules/SR012-promise-race-leak.d.ts +11 -0
- package/dist/structural-rules/rules/SR012-promise-race-leak.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR012-promise-race-leak.js +191 -0
- package/dist/structural-rules/rules/SR012-promise-race-leak.js.map +1 -0
- package/dist/structural-rules/rules/SR013-missing-idempotency-key.d.ts +11 -0
- package/dist/structural-rules/rules/SR013-missing-idempotency-key.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR013-missing-idempotency-key.js +219 -0
- package/dist/structural-rules/rules/SR013-missing-idempotency-key.js.map +1 -0
- package/dist/structural-rules/rules/SR014-mutable-closure-async.d.ts +11 -0
- package/dist/structural-rules/rules/SR014-mutable-closure-async.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR014-mutable-closure-async.js +208 -0
- package/dist/structural-rules/rules/SR014-mutable-closure-async.js.map +1 -0
- package/dist/structural-rules/rules/SR015-dangling-abort-controller.d.ts +11 -0
- package/dist/structural-rules/rules/SR015-dangling-abort-controller.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR015-dangling-abort-controller.js +190 -0
- package/dist/structural-rules/rules/SR015-dangling-abort-controller.js.map +1 -0
- package/dist/structural-rules/rules/SR016-unsafe-json-parse.d.ts +11 -0
- package/dist/structural-rules/rules/SR016-unsafe-json-parse.d.ts.map +1 -0
- package/dist/structural-rules/rules/SR016-unsafe-json-parse.js +187 -0
- package/dist/structural-rules/rules/SR016-unsafe-json-parse.js.map +1 -0
- package/dist/structural-rules/suppressions.d.ts +43 -0
- package/dist/structural-rules/suppressions.d.ts.map +1 -0
- package/dist/structural-rules/suppressions.js +115 -0
- package/dist/structural-rules/suppressions.js.map +1 -0
- package/dist/structural-rules/types.d.ts +55 -0
- package/dist/structural-rules/types.d.ts.map +1 -0
- package/dist/structural-rules/types.js +3 -0
- package/dist/structural-rules/types.js.map +1 -0
- package/dist/utils/brain-cache.d.ts +100 -0
- package/dist/utils/brain-cache.d.ts.map +1 -0
- package/dist/utils/brain-cache.js +346 -0
- package/dist/utils/brain-cache.js.map +1 -0
- package/dist/utils/governance-provenance.d.ts +95 -0
- package/dist/utils/governance-provenance.d.ts.map +1 -0
- package/dist/utils/governance-provenance.js +187 -0
- package/dist/utils/governance-provenance.js.map +1 -0
- package/dist/utils/pilot-metrics.d.ts +46 -0
- package/dist/utils/pilot-metrics.d.ts.map +1 -0
- package/dist/utils/pilot-metrics.js +240 -0
- package/dist/utils/pilot-metrics.js.map +1 -0
- package/dist/utils/replay-runtime.d.ts +34 -0
- package/dist/utils/replay-runtime.d.ts.map +1 -1
- package/dist/utils/replay-runtime.js +207 -0
- package/dist/utils/replay-runtime.js.map +1 -1
- package/dist/utils/verify-runtime-stability.d.ts +142 -0
- package/dist/utils/verify-runtime-stability.d.ts.map +1 -0
- package/dist/utils/verify-runtime-stability.js +230 -0
- package/dist/utils/verify-runtime-stability.js.map +1 -0
- package/dist/workspace/cross-repo-graph.d.ts +111 -0
- package/dist/workspace/cross-repo-graph.d.ts.map +1 -0
- package/dist/workspace/cross-repo-graph.js +450 -0
- package/dist/workspace/cross-repo-graph.js.map +1 -0
- package/dist/workspace/federated-context.d.ts +144 -0
- package/dist/workspace/federated-context.d.ts.map +1 -0
- package/dist/workspace/federated-context.js +347 -0
- package/dist/workspace/federated-context.js.map +1 -0
- package/dist/workspace/index.d.ts +38 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +48 -0
- package/dist/workspace/index.js.map +1 -0
- package/package.json +9 -9
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff Line Provenance (Phase 2 — Diff-Scoped Enforcement)
|
|
3
|
+
*
|
|
4
|
+
* Builds a per-file index of which line numbers were modified in the current
|
|
5
|
+
* diff. Used to classify structural violations as either:
|
|
6
|
+
*
|
|
7
|
+
* introducedOnModifiedLine: true → violation sits on a changed line
|
|
8
|
+
* → BLOCKING eligible (normal behaviour)
|
|
9
|
+
*
|
|
10
|
+
* introducedOnModifiedLine: false → violation is on an unmodified line
|
|
11
|
+
* → demoted to ADVISORY, tagged legacyDebt
|
|
12
|
+
*
|
|
13
|
+
* Only added diff lines are indexed (type === 'added'). Removed lines are by
|
|
14
|
+
* definition gone from the file and cannot carry current violations.
|
|
15
|
+
*
|
|
16
|
+
* The index is a Map<filePath, Set<1-based line number>> built entirely from
|
|
17
|
+
* the parsed diff — no disk I/O.
|
|
18
|
+
*/
|
|
19
|
+
import type { DiffFile } from '@neurcode-ai/diff-parser';
|
|
20
|
+
import type { StructuralViolation } from '../structural-rules/types';
|
|
21
|
+
/** Maps relative file path → set of 1-based line numbers that were added/modified. */
|
|
22
|
+
export type ModifiedLineIndex = Map<string, Set<number>>;
|
|
23
|
+
/**
|
|
24
|
+
* Build a modified-line index from a parsed diff.
|
|
25
|
+
*
|
|
26
|
+
* For each file in the diff, collect all line numbers that are 'added' in any
|
|
27
|
+
* hunk. These are the only lines that could carry new violations.
|
|
28
|
+
*
|
|
29
|
+
* Hunk format from diff-parser: each hunk has a `newStart` (1-based line
|
|
30
|
+
* number of the first line in the post-diff file) and lines with type
|
|
31
|
+
* 'added' | 'removed' | 'context'.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildModifiedLineIndex(diffFiles: DiffFile[]): ModifiedLineIndex;
|
|
34
|
+
/**
|
|
35
|
+
* Classify a structural violation's provenance against the modified-line index.
|
|
36
|
+
*
|
|
37
|
+
* Returns a new StructuralViolation (never mutates the input) with:
|
|
38
|
+
* - introducedOnModifiedLine set
|
|
39
|
+
* - legacyDebt set if demoting
|
|
40
|
+
* - severity demoted to ADVISORY if legacyDebt
|
|
41
|
+
*
|
|
42
|
+
* @param violation The raw violation from the rule engine
|
|
43
|
+
* @param index The modified-line index for this diff
|
|
44
|
+
* @param strictMode If true (--strict-full-file), skip demotion entirely
|
|
45
|
+
*/
|
|
46
|
+
export declare function classifyViolationProvenance(violation: StructuralViolation, index: ModifiedLineIndex, strictMode?: boolean): StructuralViolation;
|
|
47
|
+
/**
|
|
48
|
+
* Apply provenance classification to a batch of violations.
|
|
49
|
+
*
|
|
50
|
+
* @param violations Raw violations from rule engine
|
|
51
|
+
* @param index Modified-line index for this diff
|
|
52
|
+
* @param strictMode If true, no demotion applied (--strict-full-file)
|
|
53
|
+
*/
|
|
54
|
+
export declare function applyDiffScopedProvenance(violations: StructuralViolation[], index: ModifiedLineIndex, strictMode?: boolean): {
|
|
55
|
+
violations: StructuralViolation[];
|
|
56
|
+
legacyDebtCount: number;
|
|
57
|
+
newViolationCount: number;
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=diff-line-provenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-line-provenance.d.ts","sourceRoot":"","sources":["../../src/governance/diff-line-provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAIrE,sFAAsF;AACtF,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAIzD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CA4B/E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,mBAAmB,EAC9B,KAAK,EAAE,iBAAiB,EACxB,UAAU,UAAQ,GACjB,mBAAmB,CA0BrB;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,mBAAmB,EAAE,EACjC,KAAK,EAAE,iBAAiB,EACxB,UAAU,UAAQ,GACjB;IACD,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAgBA"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Diff Line Provenance (Phase 2 — Diff-Scoped Enforcement)
|
|
4
|
+
*
|
|
5
|
+
* Builds a per-file index of which line numbers were modified in the current
|
|
6
|
+
* diff. Used to classify structural violations as either:
|
|
7
|
+
*
|
|
8
|
+
* introducedOnModifiedLine: true → violation sits on a changed line
|
|
9
|
+
* → BLOCKING eligible (normal behaviour)
|
|
10
|
+
*
|
|
11
|
+
* introducedOnModifiedLine: false → violation is on an unmodified line
|
|
12
|
+
* → demoted to ADVISORY, tagged legacyDebt
|
|
13
|
+
*
|
|
14
|
+
* Only added diff lines are indexed (type === 'added'). Removed lines are by
|
|
15
|
+
* definition gone from the file and cannot carry current violations.
|
|
16
|
+
*
|
|
17
|
+
* The index is a Map<filePath, Set<1-based line number>> built entirely from
|
|
18
|
+
* the parsed diff — no disk I/O.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.buildModifiedLineIndex = buildModifiedLineIndex;
|
|
22
|
+
exports.classifyViolationProvenance = classifyViolationProvenance;
|
|
23
|
+
exports.applyDiffScopedProvenance = applyDiffScopedProvenance;
|
|
24
|
+
// ── Public API ────────────────────────────────────────────────────────────────
|
|
25
|
+
/**
|
|
26
|
+
* Build a modified-line index from a parsed diff.
|
|
27
|
+
*
|
|
28
|
+
* For each file in the diff, collect all line numbers that are 'added' in any
|
|
29
|
+
* hunk. These are the only lines that could carry new violations.
|
|
30
|
+
*
|
|
31
|
+
* Hunk format from diff-parser: each hunk has a `newStart` (1-based line
|
|
32
|
+
* number of the first line in the post-diff file) and lines with type
|
|
33
|
+
* 'added' | 'removed' | 'context'.
|
|
34
|
+
*/
|
|
35
|
+
function buildModifiedLineIndex(diffFiles) {
|
|
36
|
+
const index = new Map();
|
|
37
|
+
for (const file of diffFiles) {
|
|
38
|
+
const modifiedLines = new Set();
|
|
39
|
+
for (const hunk of file.hunks ?? []) {
|
|
40
|
+
// newStart is the 1-based line number of the first line in the new file
|
|
41
|
+
let currentNewLine = hunk.newStart ?? 1;
|
|
42
|
+
for (const line of hunk.lines ?? []) {
|
|
43
|
+
if (line.type === 'added') {
|
|
44
|
+
modifiedLines.add(currentNewLine);
|
|
45
|
+
currentNewLine++;
|
|
46
|
+
}
|
|
47
|
+
else if (line.type === 'context') {
|
|
48
|
+
// Context lines advance the new-file line counter but are not modified
|
|
49
|
+
currentNewLine++;
|
|
50
|
+
}
|
|
51
|
+
// Removed lines don't appear in the new file, don't advance new counter
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (modifiedLines.size > 0) {
|
|
55
|
+
index.set(file.path, modifiedLines);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return index;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Classify a structural violation's provenance against the modified-line index.
|
|
62
|
+
*
|
|
63
|
+
* Returns a new StructuralViolation (never mutates the input) with:
|
|
64
|
+
* - introducedOnModifiedLine set
|
|
65
|
+
* - legacyDebt set if demoting
|
|
66
|
+
* - severity demoted to ADVISORY if legacyDebt
|
|
67
|
+
*
|
|
68
|
+
* @param violation The raw violation from the rule engine
|
|
69
|
+
* @param index The modified-line index for this diff
|
|
70
|
+
* @param strictMode If true (--strict-full-file), skip demotion entirely
|
|
71
|
+
*/
|
|
72
|
+
function classifyViolationProvenance(violation, index, strictMode = false) {
|
|
73
|
+
// In strict full-file mode, do not apply diff-scoping
|
|
74
|
+
if (strictMode)
|
|
75
|
+
return violation;
|
|
76
|
+
const modifiedLines = index.get(violation.filePath);
|
|
77
|
+
// File not in diff at all — should not happen (we only analyze diff files)
|
|
78
|
+
// but treat conservatively: do not demote, leave unclassified
|
|
79
|
+
if (!modifiedLines) {
|
|
80
|
+
return { ...violation, introducedOnModifiedLine: false, legacyDebt: true, severity: 'ADVISORY' };
|
|
81
|
+
}
|
|
82
|
+
const onModifiedLine = modifiedLines.has(violation.line);
|
|
83
|
+
if (onModifiedLine) {
|
|
84
|
+
return { ...violation, introducedOnModifiedLine: true };
|
|
85
|
+
}
|
|
86
|
+
// Violation is on an unmodified (historical) line — demote
|
|
87
|
+
return {
|
|
88
|
+
...violation,
|
|
89
|
+
introducedOnModifiedLine: false,
|
|
90
|
+
legacyDebt: true,
|
|
91
|
+
// Demote BLOCKING → ADVISORY for legacy debt; ADVISORY stays ADVISORY
|
|
92
|
+
severity: 'ADVISORY',
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Apply provenance classification to a batch of violations.
|
|
97
|
+
*
|
|
98
|
+
* @param violations Raw violations from rule engine
|
|
99
|
+
* @param index Modified-line index for this diff
|
|
100
|
+
* @param strictMode If true, no demotion applied (--strict-full-file)
|
|
101
|
+
*/
|
|
102
|
+
function applyDiffScopedProvenance(violations, index, strictMode = false) {
|
|
103
|
+
const result = [];
|
|
104
|
+
let legacyDebtCount = 0;
|
|
105
|
+
let newViolationCount = 0;
|
|
106
|
+
for (const v of violations) {
|
|
107
|
+
const classified = classifyViolationProvenance(v, index, strictMode);
|
|
108
|
+
result.push(classified);
|
|
109
|
+
if (classified.legacyDebt) {
|
|
110
|
+
legacyDebtCount++;
|
|
111
|
+
}
|
|
112
|
+
else if (classified.introducedOnModifiedLine === true) {
|
|
113
|
+
newViolationCount++;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return { violations: result, legacyDebtCount, newViolationCount };
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=diff-line-provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-line-provenance.js","sourceRoot":"","sources":["../../src/governance/diff-line-provenance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pilot Readiness Validator (Phase 6 — Pilot Readiness Hardening)
|
|
3
|
+
*
|
|
4
|
+
* Checks that a repository meets all prerequisites for a reliable Neurcode
|
|
5
|
+
* onboarding. Designed to be runnable in under 10 seconds with no external
|
|
6
|
+
* network calls.
|
|
7
|
+
*
|
|
8
|
+
* Usage: runPilotReadinessCheck(projectRoot) → PilotReadinessReport
|
|
9
|
+
*
|
|
10
|
+
* Returns:
|
|
11
|
+
* ready: true if all blockers pass (warnings are non-blocking)
|
|
12
|
+
* blockers: list of hard failures that prevent governance from running
|
|
13
|
+
* warnings: list of soft issues that degrade experience but don't block
|
|
14
|
+
*/
|
|
15
|
+
export interface PilotReadinessReport {
|
|
16
|
+
ready: boolean;
|
|
17
|
+
blockers: string[];
|
|
18
|
+
warnings: string[];
|
|
19
|
+
checks: PilotReadinessCheck[];
|
|
20
|
+
durationMs: number;
|
|
21
|
+
}
|
|
22
|
+
export interface PilotReadinessCheck {
|
|
23
|
+
name: string;
|
|
24
|
+
status: 'pass' | 'warn' | 'fail';
|
|
25
|
+
message: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Run all pilot readiness checks for a repository.
|
|
29
|
+
*
|
|
30
|
+
* @param projectRoot Absolute path to the project root
|
|
31
|
+
* @returns PilotReadinessReport with ready flag, blockers, warnings, and per-check results
|
|
32
|
+
*/
|
|
33
|
+
export declare function runPilotReadinessCheck(projectRoot: string): PilotReadinessReport;
|
|
34
|
+
//# sourceMappingURL=pilot-readiness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pilot-readiness.d.ts","sourceRoot":"","sources":["../../src/governance/pilot-readiness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB;AAuLD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,oBAAoB,CA6BhF"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pilot Readiness Validator (Phase 6 — Pilot Readiness Hardening)
|
|
4
|
+
*
|
|
5
|
+
* Checks that a repository meets all prerequisites for a reliable Neurcode
|
|
6
|
+
* onboarding. Designed to be runnable in under 10 seconds with no external
|
|
7
|
+
* network calls.
|
|
8
|
+
*
|
|
9
|
+
* Usage: runPilotReadinessCheck(projectRoot) → PilotReadinessReport
|
|
10
|
+
*
|
|
11
|
+
* Returns:
|
|
12
|
+
* ready: true if all blockers pass (warnings are non-blocking)
|
|
13
|
+
* blockers: list of hard failures that prevent governance from running
|
|
14
|
+
* warnings: list of soft issues that degrade experience but don't block
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.runPilotReadinessCheck = runPilotReadinessCheck;
|
|
18
|
+
const fs_1 = require("fs");
|
|
19
|
+
const path_1 = require("path");
|
|
20
|
+
const child_process_1 = require("child_process");
|
|
21
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
22
|
+
function check(name, fn) {
|
|
23
|
+
try {
|
|
24
|
+
const result = fn();
|
|
25
|
+
return { name, ...result };
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
return {
|
|
29
|
+
name,
|
|
30
|
+
status: 'fail',
|
|
31
|
+
message: `Check threw unexpectedly: ${e instanceof Error ? e.message : String(e)}`,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function nodeVersion() {
|
|
36
|
+
const v = process.version; // e.g. 'v18.12.0'
|
|
37
|
+
return parseInt(v.slice(1).split('.')[0] ?? '0', 10);
|
|
38
|
+
}
|
|
39
|
+
// ── Individual checks ─────────────────────────────────────────────────────────
|
|
40
|
+
function checkGitAvailable() {
|
|
41
|
+
try {
|
|
42
|
+
(0, child_process_1.execSync)('git --version', { stdio: 'ignore', timeout: 3000 });
|
|
43
|
+
return { status: 'pass', message: 'git is available.' };
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return { status: 'fail', message: 'git is not available in PATH. Neurcode requires git to compute diffs.' };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function checkNodeVersion() {
|
|
50
|
+
const major = nodeVersion();
|
|
51
|
+
if (major >= 20)
|
|
52
|
+
return { status: 'pass', message: `Node.js v${major} (≥20 recommended).` };
|
|
53
|
+
if (major >= 18)
|
|
54
|
+
return { status: 'pass', message: `Node.js v${major} (supported; v20+ recommended for best performance).` };
|
|
55
|
+
return { status: 'fail', message: `Node.js v${major} is below minimum requirement (18). Upgrade to Node.js 18 or later.` };
|
|
56
|
+
}
|
|
57
|
+
function checkNeurcodeDir(projectRoot) {
|
|
58
|
+
const dir = (0, path_1.join)(projectRoot, '.neurcode');
|
|
59
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
60
|
+
// Not existing is fine — it will be created on first run
|
|
61
|
+
// But check that the parent directory is writable
|
|
62
|
+
try {
|
|
63
|
+
(0, fs_1.accessSync)(projectRoot, fs_1.constants.W_OK);
|
|
64
|
+
return { status: 'pass', message: '.neurcode/ does not exist yet (will be created on first verify run). Project root is writable.' };
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return { status: 'fail', message: `Project root '${projectRoot}' is not writable. Cannot create .neurcode/ directory.` };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
(0, fs_1.accessSync)(dir, fs_1.constants.W_OK);
|
|
72
|
+
return { status: 'pass', message: '.neurcode/ directory exists and is writable.' };
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return { status: 'fail', message: '.neurcode/ directory exists but is not writable. Check file permissions.' };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function checkPolicyLock(projectRoot) {
|
|
79
|
+
const lockPath = (0, path_1.join)(projectRoot, '.neurcode', 'neurcode.policy.lock.json');
|
|
80
|
+
if (!(0, fs_1.existsSync)(lockPath)) {
|
|
81
|
+
return {
|
|
82
|
+
status: 'warn',
|
|
83
|
+
message: 'Policy lock file (neurcode.policy.lock.json) not found. Run `neurcode policy bootstrap` to create it.',
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const raw = (0, fs_1.readFileSync)(lockPath, 'utf-8');
|
|
88
|
+
const parsed = JSON.parse(raw);
|
|
89
|
+
if (typeof parsed === 'object' && parsed !== null) {
|
|
90
|
+
return { status: 'pass', message: 'Policy lock file exists and is valid JSON.' };
|
|
91
|
+
}
|
|
92
|
+
return { status: 'warn', message: 'Policy lock file exists but content is not a valid JSON object.' };
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return { status: 'fail', message: 'Policy lock file exists but is corrupt (invalid JSON). Delete and re-run `neurcode policy bootstrap`.' };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function checkCacheHealth(projectRoot) {
|
|
99
|
+
const cachePath = (0, path_1.join)(projectRoot, '.neurcode', 'structural-cache.json');
|
|
100
|
+
if (!(0, fs_1.existsSync)(cachePath)) {
|
|
101
|
+
return { status: 'pass', message: 'No structural cache found (cold start — normal for first run).' };
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const raw = (0, fs_1.readFileSync)(cachePath, 'utf-8');
|
|
105
|
+
const parsed = JSON.parse(raw);
|
|
106
|
+
if (typeof parsed === 'object' &&
|
|
107
|
+
parsed !== null &&
|
|
108
|
+
typeof parsed.version === 'number' &&
|
|
109
|
+
typeof parsed.entries === 'object') {
|
|
110
|
+
const entryCount = Object.keys(parsed.entries).length;
|
|
111
|
+
return { status: 'pass', message: `Structural cache exists and is valid (${entryCount} entries).` };
|
|
112
|
+
}
|
|
113
|
+
return { status: 'warn', message: 'Structural cache exists but has unexpected format. It will be regenerated on next verify run.' };
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return { status: 'warn', message: 'Structural cache file is corrupt. It will be regenerated on next verify run.' };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function checkRepoCompatibility(projectRoot) {
|
|
120
|
+
// Detect potentially unsupported repo configurations
|
|
121
|
+
const cargoToml = (0, path_1.join)(projectRoot, 'Cargo.toml');
|
|
122
|
+
const goMod = (0, path_1.join)(projectRoot, 'go.mod');
|
|
123
|
+
const packageJson = (0, path_1.join)(projectRoot, 'package.json');
|
|
124
|
+
const requirementsTxt = (0, path_1.join)(projectRoot, 'requirements.txt');
|
|
125
|
+
const pyprojectToml = (0, path_1.join)(projectRoot, 'pyproject.toml');
|
|
126
|
+
const pomXml = (0, path_1.join)(projectRoot, 'pom.xml');
|
|
127
|
+
const detected = [];
|
|
128
|
+
if ((0, fs_1.existsSync)(packageJson))
|
|
129
|
+
detected.push('Node.js/TypeScript');
|
|
130
|
+
if ((0, fs_1.existsSync)(requirementsTxt) || (0, fs_1.existsSync)(pyprojectToml))
|
|
131
|
+
detected.push('Python');
|
|
132
|
+
if ((0, fs_1.existsSync)(goMod))
|
|
133
|
+
detected.push('Go');
|
|
134
|
+
if ((0, fs_1.existsSync)(pomXml))
|
|
135
|
+
detected.push('Java/Maven');
|
|
136
|
+
if ((0, fs_1.existsSync)(cargoToml))
|
|
137
|
+
detected.push('Rust');
|
|
138
|
+
if (detected.length === 0) {
|
|
139
|
+
return {
|
|
140
|
+
status: 'warn',
|
|
141
|
+
message: 'No recognized dependency manifest found (package.json, requirements.txt, go.mod, pom.xml). ' +
|
|
142
|
+
'Repo may be unsupported. Structural rules will run in degraded mode.',
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if ((0, fs_1.existsSync)(cargoToml) && detected.length === 1) {
|
|
146
|
+
return {
|
|
147
|
+
status: 'warn',
|
|
148
|
+
message: 'Pure Rust repository detected. Structural rules currently support TypeScript, JavaScript, and Python. ' +
|
|
149
|
+
'Policy engine will still run; structural analysis will be limited.',
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
status: 'pass',
|
|
154
|
+
message: `Detected ecosystem(s): ${detected.join(', ')}. Structural rules are supported.`,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function checkGitRepo(projectRoot) {
|
|
158
|
+
const gitDir = (0, path_1.join)(projectRoot, '.git');
|
|
159
|
+
if (!(0, fs_1.existsSync)(gitDir)) {
|
|
160
|
+
return {
|
|
161
|
+
status: 'fail',
|
|
162
|
+
message: 'Not a git repository (no .git directory found). Neurcode requires git history to compute diffs.',
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
return { status: 'pass', message: 'Git repository detected.' };
|
|
166
|
+
}
|
|
167
|
+
function checkActivePlan(projectRoot) {
|
|
168
|
+
// Check for a plan state file — existence indicates a plan is linked
|
|
169
|
+
const stateFile = (0, path_1.join)(projectRoot, '.neurcode', 'state.json');
|
|
170
|
+
if (!(0, fs_1.existsSync)(stateFile)) {
|
|
171
|
+
return {
|
|
172
|
+
status: 'warn',
|
|
173
|
+
message: 'No Neurcode state file found. Run `neurcode plan` to set an intent before verifying. ' +
|
|
174
|
+
'Without a plan, verify runs in advisory-only mode.',
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
const raw = (0, fs_1.readFileSync)(stateFile, 'utf-8');
|
|
179
|
+
const state = JSON.parse(raw);
|
|
180
|
+
const planId = state.activePlanId ?? state.planId;
|
|
181
|
+
if (planId && typeof planId === 'string') {
|
|
182
|
+
return { status: 'pass', message: `Active plan detected: ${planId.slice(0, 16)}...` };
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
status: 'warn',
|
|
186
|
+
message: 'State file found but no active plan linked. Run `neurcode plan` to set intent.',
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return { status: 'warn', message: 'State file is unreadable. Run `neurcode plan` to re-link a plan.' };
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// ── Main entry point ──────────────────────────────────────────────────────────
|
|
194
|
+
/**
|
|
195
|
+
* Run all pilot readiness checks for a repository.
|
|
196
|
+
*
|
|
197
|
+
* @param projectRoot Absolute path to the project root
|
|
198
|
+
* @returns PilotReadinessReport with ready flag, blockers, warnings, and per-check results
|
|
199
|
+
*/
|
|
200
|
+
function runPilotReadinessCheck(projectRoot) {
|
|
201
|
+
const startMs = Date.now();
|
|
202
|
+
const checks = [
|
|
203
|
+
check('git-available', () => checkGitAvailable()),
|
|
204
|
+
check('git-repository', () => checkGitRepo(projectRoot)),
|
|
205
|
+
check('node-version', () => checkNodeVersion()),
|
|
206
|
+
check('neurcode-dir', () => checkNeurcodeDir(projectRoot)),
|
|
207
|
+
check('repo-compatibility', () => checkRepoCompatibility(projectRoot)),
|
|
208
|
+
check('policy-lock', () => checkPolicyLock(projectRoot)),
|
|
209
|
+
check('cache-health', () => checkCacheHealth(projectRoot)),
|
|
210
|
+
check('active-plan', () => checkActivePlan(projectRoot)),
|
|
211
|
+
];
|
|
212
|
+
const blockers = checks
|
|
213
|
+
.filter(c => c.status === 'fail')
|
|
214
|
+
.map(c => `[${c.name}] ${c.message}`);
|
|
215
|
+
const warnings = checks
|
|
216
|
+
.filter(c => c.status === 'warn')
|
|
217
|
+
.map(c => `[${c.name}] ${c.message}`);
|
|
218
|
+
return {
|
|
219
|
+
ready: blockers.length === 0,
|
|
220
|
+
blockers,
|
|
221
|
+
warnings,
|
|
222
|
+
checks,
|
|
223
|
+
durationMs: Date.now() - startMs,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=pilot-readiness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pilot-readiness.js","sourceRoot":"","sources":["../../src/governance/pilot-readiness.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;AAiNH,wDA6BC;AA5OD,2BAA+E;AAC/E,+BAA4B;AAC5B,iDAAyC;AAkBzC,iFAAiF;AAEjF,SAAS,KAAK,CACZ,IAAY,EACZ,EAA+D;IAE/D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,EAAE,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;IAC7B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,6BAA6B,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;SACnF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,kBAAkB;IAC7C,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,iFAAiF;AAEjF,SAAS,iBAAiB;IACxB,IAAI,CAAC;QACH,IAAA,wBAAQ,EAAC,eAAe,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,uEAAuE,EAAE,CAAC;IAC9G,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB;IACvB,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;IAC5B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,KAAK,qBAAqB,EAAE,CAAC;IAC5F,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,KAAK,sDAAsD,EAAE,CAAC;IAC7H,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,KAAK,qEAAqE,EAAE,CAAC;AAC7H,CAAC;AAED,SAAS,gBAAgB,CAAC,WAAmB;IAC3C,MAAM,GAAG,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAA,eAAU,EAAC,GAAG,CAAC,EAAE,CAAC;QACrB,yDAAyD;QACzD,kDAAkD;QAClD,IAAI,CAAC;YACH,IAAA,eAAU,EAAC,WAAW,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;YACxC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gGAAgG,EAAE,CAAC;QACvI,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,WAAW,wDAAwD,EAAE,CAAC;QAC3H,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACH,IAAA,eAAU,EAAC,GAAG,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,8CAA8C,EAAE,CAAC;IACrF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,0EAA0E,EAAE,CAAC;IACjH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,WAAmB;IAC1C,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,WAAW,EAAE,2BAA2B,CAAC,CAAC;IAC7E,IAAI,CAAC,IAAA,eAAU,EAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,uGAAuG;SACjH,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,iBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QAC1C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,4CAA4C,EAAE,CAAC;QACnF,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iEAAiE,EAAE,CAAC;IACxG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,uGAAuG,EAAE,CAAC;IAC9I,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,WAAmB;IAC3C,MAAM,SAAS,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,WAAW,EAAE,uBAAuB,CAAC,CAAC;IAC1E,IAAI,CAAC,IAAA,eAAU,EAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gEAAgE,EAAE,CAAC;IACvG,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,iBAAY,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QAC1C,IACE,OAAO,MAAM,KAAK,QAAQ;YAC1B,MAAM,KAAK,IAAI;YACf,OAAQ,MAAkC,CAAC,OAAO,KAAK,QAAQ;YAC/D,OAAQ,MAAkC,CAAC,OAAO,KAAK,QAAQ,EAC/D,CAAC;YACD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAE,MAA+C,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;YAChG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,yCAAyC,UAAU,YAAY,EAAE,CAAC;QACtG,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,+FAA+F,EAAE,CAAC;IACtI,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,8EAA8E,EAAE,CAAC;IACrH,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,WAAmB;IACjD,qDAAqD;IACrD,MAAM,SAAS,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IACtD,MAAM,eAAe,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;IAC9D,MAAM,aAAa,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAE5C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,IAAA,eAAU,EAAC,WAAW,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACjE,IAAI,IAAA,eAAU,EAAC,eAAe,CAAC,IAAI,IAAA,eAAU,EAAC,aAAa,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtF,IAAI,IAAA,eAAU,EAAC,KAAK,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,IAAA,eAAU,EAAC,MAAM,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACpD,IAAI,IAAA,eAAU,EAAC,SAAS,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEjD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,6FAA6F;gBAC7F,sEAAsE;SAChF,CAAC;IACJ,CAAC;IAED,IAAI,IAAA,eAAU,EAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,OAAO;YACL,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,wGAAwG;gBACxG,oEAAoE;SAC9E,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,0BAA0B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,mCAAmC;KAC1F,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,WAAmB;IACvC,MAAM,MAAM,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,IAAA,eAAU,EAAC,MAAM,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,iGAAiG;SAC3G,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC;AACjE,CAAC;AAED,SAAS,eAAe,CAAC,WAAmB;IAC1C,qEAAqE;IACrE,MAAM,SAAS,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IAC/D,IAAI,CAAC,IAAA,eAAU,EAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,uFAAuF;gBACvF,oDAAoD;SAC9D,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,iBAAY,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;QACzD,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC;QAClD,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YACzC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC;QACxF,CAAC;QACD,OAAO;YACL,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,gFAAgF;SAC1F,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,kEAAkE,EAAE,CAAC;IACzG,CAAC;AACH,CAAC;AAED,iFAAiF;AAEjF;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,WAAmB;IACxD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE3B,MAAM,MAAM,GAA0B;QACpC,KAAK,CAAC,eAAe,EAAO,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC;QACtD,KAAK,CAAC,gBAAgB,EAAM,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QAC5D,KAAK,CAAC,cAAc,EAAQ,GAAG,EAAE,CAAC,gBAAgB,EAAE,CAAC;QACrD,KAAK,CAAC,cAAc,EAAQ,GAAG,EAAE,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAChE,KAAK,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC;QACtE,KAAK,CAAC,aAAa,EAAS,GAAG,EAAE,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QAC/D,KAAK,CAAC,cAAc,EAAQ,GAAG,EAAE,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAChE,KAAK,CAAC,aAAa,EAAS,GAAG,EAAE,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;KAChE,CAAC;IAEF,MAAM,QAAQ,GAAG,MAAM;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAExC,MAAM,QAAQ,GAAG,MAAM;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAExC,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC;QAC5B,QAAQ;QACR,QAAQ;QACR,MAAM;QACN,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;KACjC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Enforcement Parity Validator
|
|
3
|
+
*
|
|
4
|
+
* Closes the governance theatre gap: a policy can appear in policy.yml
|
|
5
|
+
* claiming "deterministic" enforcement, but have zero structural rule
|
|
6
|
+
* implementation. This validator surfaces those mismatches explicitly.
|
|
7
|
+
*
|
|
8
|
+
* Benchmark finding (Apache Airflow, 2026-05-12):
|
|
9
|
+
* 7 of 15 policies were unenforced. Enterprise teams believed those
|
|
10
|
+
* policies were being checked. They were not.
|
|
11
|
+
*
|
|
12
|
+
* This module is called from `neurcode verify --policy-only` to emit
|
|
13
|
+
* GOV_PARITY_MISMATCH advisory findings for every enforcement gap.
|
|
14
|
+
*/
|
|
15
|
+
export type EnforcementType = 'deterministic' | 'advisory' | 'semantic' | 'none';
|
|
16
|
+
export interface PolicyParityEntry {
|
|
17
|
+
ruleId: string;
|
|
18
|
+
name?: string;
|
|
19
|
+
enforcementType: EnforcementType;
|
|
20
|
+
hasStructuralImpl: boolean;
|
|
21
|
+
hasPolicyEngineImpl: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface PolicyParityReport {
|
|
24
|
+
totalPolicies: number;
|
|
25
|
+
deterministicCount: number;
|
|
26
|
+
advisoryCount: number;
|
|
27
|
+
semanticCount: number;
|
|
28
|
+
noneCount: number;
|
|
29
|
+
/** Percentage of policies with deterministic structural enforcement (0-100) */
|
|
30
|
+
coveragePct: number;
|
|
31
|
+
/** Policies claiming deterministic but with no registered implementation */
|
|
32
|
+
unenforced: string[];
|
|
33
|
+
/** All entries with full detail */
|
|
34
|
+
entries: PolicyParityEntry[];
|
|
35
|
+
}
|
|
36
|
+
export interface ParityMismatchFinding {
|
|
37
|
+
ruleId: string;
|
|
38
|
+
policyName?: string;
|
|
39
|
+
message: string;
|
|
40
|
+
severity: 'advisory';
|
|
41
|
+
governanceCode: 'GOV_PARITY_MISMATCH';
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Validate enforcement parity between policy declarations and the structural rule engine.
|
|
45
|
+
*
|
|
46
|
+
* @param policyRules - Rules from the compiled/loaded policy (array of { id, name, enforcementType? })
|
|
47
|
+
* @param registeredStructuralRuleIds - Set of rule IDs currently registered in StructuralRuleEngine
|
|
48
|
+
* @returns PolicyParityReport + mismatch findings (one per unenforced deterministic policy)
|
|
49
|
+
*/
|
|
50
|
+
export declare function validatePolicyEnforcementParity(policyRules: Array<{
|
|
51
|
+
id: string;
|
|
52
|
+
name?: string;
|
|
53
|
+
enforcementType?: string;
|
|
54
|
+
}>, registeredStructuralRuleIds: Set<string>): {
|
|
55
|
+
report: PolicyParityReport;
|
|
56
|
+
findings: ParityMismatchFinding[];
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Generate a compact governance coverage summary string for CLI output.
|
|
60
|
+
*/
|
|
61
|
+
export declare function formatParityReport(report: PolicyParityReport): string;
|
|
62
|
+
//# sourceMappingURL=policy-parity-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-parity-validator.d.ts","sourceRoot":"","sources":["../../src/governance/policy-parity-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;AAEjF,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,eAAe,CAAC;IACjC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,WAAW,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,mCAAmC;IACnC,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,UAAU,CAAC;IACrB,cAAc,EAAE,qBAAqB,CAAC;CACvC;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC7C,WAAW,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAC3E,2BAA2B,EAAE,GAAG,CAAC,MAAM,CAAC,GACvC;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,QAAQ,EAAE,qBAAqB,EAAE,CAAA;CAAE,CAsEnE;AA4BD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAWrE"}
|