@deftai/directive-core 0.107.0 → 0.109.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/architecture/sor-preflight.js +2 -0
- package/dist/cache/operations.js +1 -1
- package/dist/check/cached-orchestrator.js +28 -3
- package/dist/check/gate-lists.d.ts +14 -0
- package/dist/check/gate-lists.js +26 -3
- package/dist/check/named-cause.js +18 -3
- package/dist/check/session-completed-ac.d.ts +1 -1
- package/dist/check/session-completed-ac.js +1 -1
- package/dist/codebase/provider.js +7 -1
- package/dist/consumer-check-contract/evaluate.d.ts +47 -0
- package/dist/consumer-check-contract/evaluate.js +181 -15
- package/dist/delivery-attempt/evaluate.d.ts +9 -1
- package/dist/delivery-attempt/evaluate.js +69 -0
- package/dist/delivery-attempt/handoff.js +1 -1
- package/dist/delivery-attempt/index.d.ts +1 -1
- package/dist/delivery-attempt/index.js +1 -1
- package/dist/deposit/live-procedure-exclusions.d.ts +18 -0
- package/dist/deposit/live-procedure-exclusions.js +110 -0
- package/dist/deposit/live-procedure-targets.d.ts +45 -0
- package/dist/deposit/live-procedure-targets.js +274 -0
- package/dist/deposit/python-free.d.ts +6 -0
- package/dist/deposit/python-free.js +15 -0
- package/dist/deposit/rewrite-deposit-links.d.ts +42 -0
- package/dist/deposit/rewrite-deposit-links.js +148 -0
- package/dist/deposit/run-stage-content-pack.d.ts +2 -0
- package/dist/deposit/run-stage-content-pack.js +3 -0
- package/dist/deposit/stage-content-pack.d.ts +17 -0
- package/dist/deposit/stage-content-pack.js +91 -0
- package/dist/design-critique/citation-grammar.d.ts +60 -0
- package/dist/design-critique/citation-grammar.js +303 -0
- package/dist/design-critique/completed-arc-record.d.ts +62 -0
- package/dist/design-critique/completed-arc-record.js +277 -0
- package/dist/freshness/bind.d.ts +32 -3
- package/dist/freshness/bind.js +58 -12
- package/dist/hooks/classify/host-session-identity.d.ts +89 -0
- package/dist/hooks/classify/host-session-identity.js +467 -0
- package/dist/hooks/classify/index.d.ts +3 -2
- package/dist/hooks/classify/index.js +3 -2
- package/dist/hooks/classify/paths.d.ts +9 -0
- package/dist/hooks/classify/paths.js +39 -0
- package/dist/hooks/classify/stdin.d.ts +5 -0
- package/dist/hooks/classify/stdin.js +94 -1
- package/dist/hooks/dest-form.d.ts +20 -1
- package/dist/hooks/dest-form.js +158 -21
- package/dist/hooks/dispatcher.d.ts +58 -3
- package/dist/hooks/dispatcher.js +762 -73
- package/dist/hooks/fixtures/cases.d.ts +22 -2
- package/dist/hooks/fixtures/cases.js +228 -0
- package/dist/hooks/git-destructive-log.d.ts +32 -0
- package/dist/hooks/git-destructive-log.js +46 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/scope.js +3 -1
- package/dist/hooks/shell-write-targets.d.ts +10 -0
- package/dist/hooks/shell-write-targets.js +274 -0
- package/dist/hooks/tools.d.ts +20 -2
- package/dist/hooks/tools.js +30 -1
- package/dist/init-deposit/agent-hooks.d.ts +2 -1
- package/dist/init-deposit/agent-hooks.js +8 -1
- package/dist/init-deposit/gitignore.d.ts +7 -0
- package/dist/init-deposit/gitignore.js +24 -0
- package/dist/init-deposit/hook-runtime-travel.d.ts +77 -0
- package/dist/init-deposit/hook-runtime-travel.js +269 -0
- package/dist/init-deposit/init-deposit.js +3 -0
- package/dist/init-deposit/refresh.js +7 -0
- package/dist/init-deposit/runtime-writers.d.ts +14 -0
- package/dist/init-deposit/runtime-writers.js +33 -0
- package/dist/intake/clause-derivation.js +9 -3
- package/dist/intake/issue-ingest.d.ts +6 -1
- package/dist/intake/issue-ingest.js +83 -4
- package/dist/intake/platform-capabilities.d.ts +9 -2
- package/dist/intake/platform-capabilities.js +38 -9
- package/dist/intake/reconcile-issues.js +13 -13
- package/dist/lifecycle/brief-envelope.d.ts +25 -0
- package/dist/lifecycle/brief-envelope.js +42 -0
- package/dist/lifecycle/index.d.ts +1 -0
- package/dist/lifecycle/index.js +1 -0
- package/dist/literal-acceptance/evaluate.js +14 -5
- package/dist/literal-acceptance/index.d.ts +1 -1
- package/dist/literal-acceptance/index.js +1 -1
- package/dist/literal-acceptance/run.d.ts +2 -0
- package/dist/literal-acceptance/run.js +19 -1
- package/dist/orphan-active/candidate-scope.d.ts +53 -0
- package/dist/orphan-active/candidate-scope.js +157 -0
- package/dist/orphan-active/evaluate.d.ts +52 -0
- package/dist/orphan-active/evaluate.js +250 -128
- package/dist/orphan-active/index.d.ts +2 -0
- package/dist/orphan-active/index.js +2 -0
- package/dist/orphan-active/issue-state.d.ts +121 -0
- package/dist/orphan-active/issue-state.js +278 -0
- package/dist/platform/cursor-managed-runtime.d.ts +95 -0
- package/dist/platform/cursor-managed-runtime.js +241 -0
- package/dist/platform/index.d.ts +1 -0
- package/dist/platform/index.js +1 -0
- package/dist/platform/platform-capabilities.d.ts +23 -1
- package/dist/platform/platform-capabilities.js +55 -15
- package/dist/policy/ceremony-dial.js +5 -9
- package/dist/policy/host-hooks.js +4 -9
- package/dist/policy/merge-approval-head.js +7 -6
- package/dist/policy/org-force-on-migration.js +5 -10
- package/dist/policy/plan-extensions.d.ts +14 -2
- package/dist/policy/plan-extensions.js +24 -3
- package/dist/policy/product-signal.js +5 -10
- package/dist/policy/require-human-merge.js +5 -9
- package/dist/policy/resolve.js +77 -16
- package/dist/policy/value-feedback.js +9 -18
- package/dist/pr-closeout-attestable/evaluate.d.ts +80 -0
- package/dist/pr-closeout-attestable/evaluate.js +306 -0
- package/dist/pr-closeout-attestable/index.d.ts +2 -0
- package/dist/pr-closeout-attestable/index.js +2 -0
- package/dist/pr-closing-keywords/gh.js +32 -9
- package/dist/pr-closing-keywords/main.d.ts +1 -0
- package/dist/pr-closing-keywords/main.js +68 -3
- package/dist/pr-closing-keywords/types.d.ts +2 -0
- package/dist/pr-merge-readiness/gh.js +32 -9
- package/dist/pr-protected-issues/gh.d.ts +6 -2
- package/dist/pr-protected-issues/gh.js +42 -11
- package/dist/pr-wait-mergeable/cascade.d.ts +9 -1
- package/dist/pr-wait-mergeable/cascade.js +21 -1
- package/dist/pr-wait-mergeable/types.d.ts +2 -0
- package/dist/pr-wait-mergeable/wrappers.d.ts +6 -0
- package/dist/pr-wait-mergeable/wrappers.js +14 -3
- package/dist/preflight/evaluate.d.ts +15 -0
- package/dist/preflight/evaluate.js +29 -3
- package/dist/product-first-done-gate/acceptance-resolver.d.ts +14 -2
- package/dist/product-first-done-gate/acceptance-resolver.js +13 -2
- package/dist/product-first-done-gate/evaluate.js +23 -9
- package/dist/product-first-done-gate/types.js +2 -0
- package/dist/release/cli-drift-report.d.ts +68 -0
- package/dist/release/cli-drift-report.js +189 -0
- package/dist/release/consumer-hard-stops.d.ts +48 -0
- package/dist/release/consumer-hard-stops.js +140 -0
- package/dist/release/consumer-readiness-disclosure.d.ts +18 -0
- package/dist/release/consumer-readiness-disclosure.js +51 -0
- package/dist/release/index.d.ts +3 -0
- package/dist/release/index.js +3 -0
- package/dist/release/issue-state-fetch.d.ts +5 -3
- package/dist/release/issue-state-fetch.js +86 -21
- package/dist/release/native-steps.js +1 -0
- package/dist/release/pipeline.js +74 -0
- package/dist/release/run-consumer-readiness.d.ts +15 -0
- package/dist/release/run-consumer-readiness.js +24 -0
- package/dist/release/types.d.ts +20 -0
- package/dist/render/constants.d.ts +4 -0
- package/dist/render/constants.js +11 -8
- package/dist/render/export-spec.js +31 -5
- package/dist/render/index.d.ts +1 -1
- package/dist/render/index.js +1 -1
- package/dist/render/prd-render.d.ts +4 -1
- package/dist/render/prd-render.js +82 -23
- package/dist/render/project-render.js +14 -7
- package/dist/render/scope-outlook.d.ts +2 -0
- package/dist/render/scope-outlook.js +3 -0
- package/dist/render/spec-render.js +2 -2
- package/dist/resolution/package-manager.d.ts +33 -4
- package/dist/resolution/package-manager.js +210 -9
- package/dist/review-monitor/constants.d.ts +7 -0
- package/dist/review-monitor/constants.js +7 -0
- package/dist/review-monitor/github-lease.d.ts +98 -1
- package/dist/review-monitor/github-lease.js +186 -4
- package/dist/review-monitor/lease-comment.d.ts +36 -0
- package/dist/review-monitor/lease-comment.js +103 -2
- package/dist/run-summary/types.d.ts +2 -2
- package/dist/scm/build-command.d.ts +2 -2
- package/dist/scm/build-command.js +2 -2
- package/dist/scm/call-shape.d.ts +25 -0
- package/dist/scm/call-shape.js +59 -0
- package/dist/scm/call.d.ts +7 -4
- package/dist/scm/call.js +48 -9
- package/dist/scm/design-critique-chip.d.ts +1 -0
- package/dist/scm/design-critique-chip.js +22 -6
- package/dist/scm/gh-rest.d.ts +34 -13
- package/dist/scm/gh-rest.js +168 -15
- package/dist/scm/index.d.ts +2 -0
- package/dist/scm/index.js +2 -0
- package/dist/scm/readiness.d.ts +2 -0
- package/dist/scm/readiness.js +28 -4
- package/dist/scm/spawn-status.d.ts +33 -0
- package/dist/scm/spawn-status.js +53 -0
- package/dist/scope/acceptance-evidence.d.ts +1 -1
- package/dist/scope/project-definition-sync.js +14 -7
- package/dist/scope/transition.js +4 -14
- package/dist/session/ac-pass-banking.d.ts +2 -2
- package/dist/session/ac-pass-banking.js +2 -2
- package/dist/session/git.d.ts +24 -0
- package/dist/session/git.js +138 -2
- package/dist/session/host-session-owner.d.ts +53 -0
- package/dist/session/host-session-owner.js +89 -0
- package/dist/session/index.d.ts +1 -0
- package/dist/session/index.js +1 -0
- package/dist/session/occupancy.d.ts +259 -13
- package/dist/session/occupancy.js +877 -33
- package/dist/session/ritual-sentinel.d.ts +5 -0
- package/dist/session/ritual-sentinel.js +5 -0
- package/dist/session/session-ready.d.ts +5 -1
- package/dist/session/session-ready.js +98 -8
- package/dist/session/session-start.d.ts +5 -1
- package/dist/session/session-start.js +32 -17
- package/dist/session/toolchain-preflight.d.ts +13 -3
- package/dist/session/toolchain-preflight.js +93 -18
- package/dist/session/verify-ac-session-cache.d.ts +2 -2
- package/dist/session/verify-ac-session-cache.js +2 -2
- package/dist/session/verify-session-ritual.d.ts +11 -0
- package/dist/session/verify-session-ritual.js +60 -15
- package/dist/slice/constants.d.ts +1 -1
- package/dist/spec-authority/constants.d.ts +10 -2
- package/dist/spec-authority/constants.js +53 -8
- package/dist/spec-authority/resolver.d.ts +3 -0
- package/dist/spec-authority/resolver.js +55 -7
- package/dist/subprocess/max-buffer.d.ts +14 -0
- package/dist/subprocess/max-buffer.js +15 -0
- package/dist/swarm/complete-cohort.d.ts +2 -0
- package/dist/swarm/complete-cohort.js +21 -13
- package/dist/swarm/index.d.ts +1 -0
- package/dist/swarm/index.js +1 -0
- package/dist/swarm/launch-cli.js +53 -33
- package/dist/swarm/launch.d.ts +8 -0
- package/dist/swarm/launch.js +63 -43
- package/dist/swarm/pre-dispatch-cli.js +2 -1
- package/dist/swarm/pre-dispatch.js +10 -1
- package/dist/swarm/subagent-status-dir.d.ts +27 -0
- package/dist/swarm/subagent-status-dir.js +42 -0
- package/dist/swarm/worktrees.d.ts +17 -3
- package/dist/swarm/worktrees.js +48 -4
- package/dist/triage/evaluate/worktrees.js +153 -6
- package/dist/triage/scope/mutations-core.d.ts +2 -6
- package/dist/triage/scope/mutations-core.js +23 -55
- package/dist/triage/scope-drift/add-ignore.js +5 -39
- package/dist/triage/subscribe/index.d.ts +2 -6
- package/dist/triage/subscribe/index.js +15 -65
- package/dist/triage/welcome/writers.js +15 -74
- package/dist/umbrella-current-shape/index.d.ts +51 -3
- package/dist/umbrella-current-shape/index.js +106 -18
- package/dist/validate-content/deposit-required.d.ts +39 -0
- package/dist/validate-content/deposit-required.js +147 -0
- package/dist/validate-content/index.d.ts +1 -0
- package/dist/validate-content/index.js +1 -0
- package/dist/validate-content/validate-links.d.ts +2 -3
- package/dist/validate-content/validate-links.js +29 -2
- package/dist/vbrief-activate/activate.d.ts +7 -2
- package/dist/vbrief-activate/activate.js +26 -13
- package/dist/vbrief-build/index.d.ts +2 -1
- package/dist/vbrief-build/index.js +2 -1
- package/dist/vbrief-build/parity-scenarios.js +5 -5
- package/dist/vbrief-build/project-definition-io.d.ts +63 -3
- package/dist/vbrief-build/project-definition-io.js +357 -31
- package/dist/vbrief-build/project-definition-mutation.d.ts +32 -0
- package/dist/vbrief-build/project-definition-mutation.js +43 -0
- package/dist/vbrief-validate/conformance.d.ts +1 -0
- package/dist/vbrief-validate/conformance.js +85 -8
- package/dist/vbrief-validate/main.js +2 -0
- package/dist/vbrief-validate/precutover.js +5 -10
- package/dist/verify-ac/clauses.d.ts +62 -2
- package/dist/verify-ac/clauses.js +183 -111
- package/dist/verify-ac/evaluate.d.ts +9 -0
- package/dist/verify-ac/evaluate.js +32 -9
- package/dist/verify-ac/index.d.ts +1 -1
- package/dist/verify-ac/index.js +1 -1
- package/dist/verify-env/node-runtime.d.ts +8 -4
- package/dist/verify-env/node-runtime.js +9 -6
- package/dist/verify-env/toolchain-check.d.ts +35 -3
- package/dist/verify-env/toolchain-check.js +155 -36
- package/dist/verify-source/deposit-closure.d.ts +23 -0
- package/dist/verify-source/deposit-closure.js +162 -0
- package/dist/verify-source/index.d.ts +2 -0
- package/dist/verify-source/index.js +2 -0
- package/dist/verify-source/project-definition-mutation-boundary.d.ts +104 -0
- package/dist/verify-source/project-definition-mutation-boundary.js +326 -0
- package/dist/verify-source/semantic-single-source.d.ts +36 -0
- package/dist/verify-source/semantic-single-source.js +349 -0
- package/package.json +7 -3
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* project-definition-mutation-boundary.ts -- mechanized production inventory for
|
|
3
|
+
* PROJECT-DEFINITION mutation identity (#3796).
|
|
4
|
+
*
|
|
5
|
+
* A convention that mutators "should" use the shared lock is not checkable: a
|
|
6
|
+
* caller can take the lock and then resolve, read, or write the artifact through
|
|
7
|
+
* its own path, and a helper-level test still passes while a production family
|
|
8
|
+
* split-brains. This scanner replaces that convention with a boundary.
|
|
9
|
+
*
|
|
10
|
+
* Two things are enforced:
|
|
11
|
+
*
|
|
12
|
+
* 1. **Boundary** -- outside the modules that own the protocol, no production
|
|
13
|
+
* source may call the raw lock, the raw write sink, or the raw loader, and no
|
|
14
|
+
* file that mutates PROJECT-DEFINITION may re-resolve the artifact path. The
|
|
15
|
+
* mutation capability is the only way in.
|
|
16
|
+
* 2. **Inventory** -- the per-file census of mutation call expressions is
|
|
17
|
+
* recorded. Adding or removing a mutation site is a deliberate edit to
|
|
18
|
+
* {@link PRODUCTION_MUTATION_INVENTORY}, not a silent drift.
|
|
19
|
+
*
|
|
20
|
+
* Consumed fail-closed by `project-definition-mutation-boundary.test.ts`.
|
|
21
|
+
*/
|
|
22
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
23
|
+
import { join, relative, sep } from "node:path";
|
|
24
|
+
/** The capability that owns load/parse/persist against the captured path. */
|
|
25
|
+
export const MUTATION_CAPABILITY_MODULE = "packages/core/src/vbrief-build/project-definition-mutation.ts";
|
|
26
|
+
/** The module that owns the lock protocol and the raw primitives it wraps. */
|
|
27
|
+
export const MUTATION_PROTOCOL_MODULE = "packages/core/src/vbrief-build/project-definition-io.ts";
|
|
28
|
+
/**
|
|
29
|
+
* This scanner. Excluded from its own scan: it names every pattern it looks for
|
|
30
|
+
* in prose and regex literals, so scanning it would count the rules as call
|
|
31
|
+
* sites and let the inventory drift by editing the gate.
|
|
32
|
+
*/
|
|
33
|
+
export const MUTATION_BOUNDARY_MODULE = "packages/core/src/verify-source/project-definition-mutation-boundary.ts";
|
|
34
|
+
/**
|
|
35
|
+
* Raw primitives and the only production files allowed to call them. Anything
|
|
36
|
+
* else reaching for these is a bypass of the captured-path identity.
|
|
37
|
+
*/
|
|
38
|
+
export const RAW_MUTATION_CALL_RULES = [
|
|
39
|
+
{
|
|
40
|
+
label: "raw mutation lock",
|
|
41
|
+
pattern: /\bprojectDefinitionMutationLock\s*\(/,
|
|
42
|
+
allowedFiles: [MUTATION_CAPABILITY_MODULE],
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
label: "raw PROJECT-DEFINITION write sink",
|
|
46
|
+
pattern: /\batomicWriteProjectDefinition\s*\(/,
|
|
47
|
+
allowedFiles: [MUTATION_CAPABILITY_MODULE, MUTATION_PROTOCOL_MODULE],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
label: "raw captured-path parser",
|
|
51
|
+
pattern: /\bparseProjectDefinitionAt\s*\(/,
|
|
52
|
+
allowedFiles: [MUTATION_CAPABILITY_MODULE, MUTATION_PROTOCOL_MODULE],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
label: "raw unlocked loader",
|
|
56
|
+
pattern: /\bloadProjectDefinitionForMutation\s*\(/,
|
|
57
|
+
allowedFiles: [MUTATION_PROTOCOL_MODULE],
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
/** Resolver calls that would give a mutation section a second artifact identity. */
|
|
61
|
+
export const RESOLVER_CALL_PATTERNS = [
|
|
62
|
+
/\bresolveProjectDefinitionPath\s*\(/,
|
|
63
|
+
/\bprojectDefinitionPath\s*\(/,
|
|
64
|
+
];
|
|
65
|
+
/** Marks a file as performing a PROJECT-DEFINITION mutation. */
|
|
66
|
+
const MUTATION_CALL_PATTERN = /\bwithProjectDefinitionMutation\s*\(/g;
|
|
67
|
+
/**
|
|
68
|
+
* Character offsets of each `withProjectDefinitionMutation(...)` argument list.
|
|
69
|
+
*
|
|
70
|
+
* Scoping to the section is what keeps the resolver rule precise: resolving the
|
|
71
|
+
* path *before* acquiring the lock is ordinary pre-check work, while resolving it
|
|
72
|
+
* *inside* the critical section is the second identity the contract forbids.
|
|
73
|
+
* String, template, and comment spans are skipped so their braces and parens do
|
|
74
|
+
* not throw off the match.
|
|
75
|
+
*/
|
|
76
|
+
export function extractMutationSections(text) {
|
|
77
|
+
const sections = [];
|
|
78
|
+
const call = /\bwithProjectDefinitionMutation\s*\(/g;
|
|
79
|
+
let match = call.exec(text);
|
|
80
|
+
while (match !== null) {
|
|
81
|
+
const open = match.index + match[0].length - 1;
|
|
82
|
+
const end = matchClosingParen(text, open);
|
|
83
|
+
if (end > open)
|
|
84
|
+
sections.push([open, end]);
|
|
85
|
+
call.lastIndex = end > open ? end : call.lastIndex;
|
|
86
|
+
match = call.exec(text);
|
|
87
|
+
}
|
|
88
|
+
return sections;
|
|
89
|
+
}
|
|
90
|
+
function matchClosingParen(text, openIndex) {
|
|
91
|
+
let depth = 0;
|
|
92
|
+
let i = openIndex;
|
|
93
|
+
while (i < text.length) {
|
|
94
|
+
const ch = text[i];
|
|
95
|
+
const next = text[i + 1];
|
|
96
|
+
if (ch === "/" && next === "/") {
|
|
97
|
+
while (i < text.length && text[i] !== "\n")
|
|
98
|
+
i += 1;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (ch === "/" && next === "*") {
|
|
102
|
+
i += 2;
|
|
103
|
+
while (i < text.length && !(text[i] === "*" && text[i + 1] === "/"))
|
|
104
|
+
i += 1;
|
|
105
|
+
i += 2;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
109
|
+
i = skipStringLiteral(text, i);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (ch === "(")
|
|
113
|
+
depth += 1;
|
|
114
|
+
if (ch === ")") {
|
|
115
|
+
depth -= 1;
|
|
116
|
+
if (depth === 0)
|
|
117
|
+
return i;
|
|
118
|
+
}
|
|
119
|
+
i += 1;
|
|
120
|
+
}
|
|
121
|
+
return openIndex;
|
|
122
|
+
}
|
|
123
|
+
function skipStringLiteral(text, startIndex) {
|
|
124
|
+
const quote = text[startIndex];
|
|
125
|
+
let i = startIndex + 1;
|
|
126
|
+
while (i < text.length) {
|
|
127
|
+
if (text[i] === "\\") {
|
|
128
|
+
i += 2;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (text[i] === quote)
|
|
132
|
+
return i + 1;
|
|
133
|
+
i += 1;
|
|
134
|
+
}
|
|
135
|
+
return i;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Production mutation call expressions, per file.
|
|
139
|
+
*
|
|
140
|
+
* The counts are the #3796 census: **18** call expressions across 13 core files
|
|
141
|
+
* that previously took the shared lock, plus the **2** `packages/cli` policy
|
|
142
|
+
* writers (`wipCap`, `swarmSubagentBackend`) that previously wrote
|
|
143
|
+
* PROJECT-DEFINITION with no lock at all. `parity-scenarios.ts` is the fixture
|
|
144
|
+
* harness for the same protocol and is counted separately below.
|
|
145
|
+
*/
|
|
146
|
+
export const PRODUCTION_MUTATION_INVENTORY = Object.freeze({
|
|
147
|
+
"packages/cli/src/dispatch.ts": 2,
|
|
148
|
+
"packages/core/src/policy/ceremony-dial.ts": 1,
|
|
149
|
+
"packages/core/src/policy/host-hooks.ts": 1,
|
|
150
|
+
"packages/core/src/policy/org-force-on-migration.ts": 1,
|
|
151
|
+
"packages/core/src/policy/product-signal.ts": 1,
|
|
152
|
+
"packages/core/src/policy/require-human-merge.ts": 1,
|
|
153
|
+
"packages/core/src/policy/resolve.ts": 1,
|
|
154
|
+
"packages/core/src/policy/value-feedback.ts": 2,
|
|
155
|
+
"packages/core/src/render/project-render.ts": 2,
|
|
156
|
+
"packages/core/src/scope/project-definition-sync.ts": 1,
|
|
157
|
+
"packages/core/src/triage/scope-drift/add-ignore.ts": 1,
|
|
158
|
+
"packages/core/src/triage/scope/mutations-core.ts": 2,
|
|
159
|
+
"packages/core/src/triage/subscribe/index.ts": 1,
|
|
160
|
+
"packages/core/src/triage/welcome/writers.ts": 3,
|
|
161
|
+
"packages/core/src/vbrief-build/parity-scenarios.ts": 1,
|
|
162
|
+
});
|
|
163
|
+
/**
|
|
164
|
+
* The #3796 census, split by provenance so a drift failure says which family
|
|
165
|
+
* moved. 18 core call expressions across 13 files already took the shared lock;
|
|
166
|
+
* the 2 `packages/cli` policy writers did not; `parity-scenarios.ts` is the
|
|
167
|
+
* fixture harness for the same protocol.
|
|
168
|
+
*/
|
|
169
|
+
export const PREVIOUSLY_LOCKED_CORE_CALL_EXPRESSIONS = 18;
|
|
170
|
+
export const PREVIOUSLY_LOCKED_CORE_FILES = 13;
|
|
171
|
+
export const PREVIOUSLY_UNLOCKED_CLI_WRITERS = 2;
|
|
172
|
+
export const PARITY_HARNESS_CALL_EXPRESSIONS = 1;
|
|
173
|
+
const SCAN_ROOTS = ["packages/core/src", "packages/cli/src"];
|
|
174
|
+
const TEST_PATH_MARKERS = [".test.ts", ".test.tsx", "/fixtures/"];
|
|
175
|
+
function toPosix(p) {
|
|
176
|
+
return p.split(sep).join("/");
|
|
177
|
+
}
|
|
178
|
+
function isProductionSource(relPosix) {
|
|
179
|
+
return !TEST_PATH_MARKERS.some((marker) => relPosix.includes(marker));
|
|
180
|
+
}
|
|
181
|
+
function walkTsFiles(dir, out) {
|
|
182
|
+
let entries;
|
|
183
|
+
try {
|
|
184
|
+
entries = readdirSync(dir);
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
for (const name of entries) {
|
|
190
|
+
if (name === "node_modules" || name === "dist" || name === ".git")
|
|
191
|
+
continue;
|
|
192
|
+
const full = join(dir, name);
|
|
193
|
+
let st;
|
|
194
|
+
try {
|
|
195
|
+
st = statSync(full);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (st.isDirectory()) {
|
|
201
|
+
walkTsFiles(full, out);
|
|
202
|
+
}
|
|
203
|
+
else if (st.isFile() && (name.endsWith(".ts") || name.endsWith(".tsx"))) {
|
|
204
|
+
out.push(full);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* A re-export (`export { x } from "..."`) forwards a symbol, it does not call
|
|
210
|
+
* it, so it is not a bypass. Import lines are likewise declarations.
|
|
211
|
+
*/
|
|
212
|
+
function isDeclarationLine(trimmed) {
|
|
213
|
+
return (trimmed.startsWith("import ") ||
|
|
214
|
+
trimmed.startsWith("export {") ||
|
|
215
|
+
trimmed.startsWith("export type {") ||
|
|
216
|
+
trimmed.startsWith("export *") ||
|
|
217
|
+
trimmed.startsWith("//") ||
|
|
218
|
+
trimmed.startsWith("*") ||
|
|
219
|
+
trimmed.startsWith("/*"));
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Scan production TypeScript for mutation-identity bypasses and build the
|
|
223
|
+
* mutation call-expression inventory. The scan reads the filesystem, not the git
|
|
224
|
+
* index, so an unstaged or brand-new bypass is still caught.
|
|
225
|
+
*/
|
|
226
|
+
export function scanProjectDefinitionMutationBoundary(projectRoot) {
|
|
227
|
+
const files = [];
|
|
228
|
+
for (const root of SCAN_ROOTS) {
|
|
229
|
+
walkTsFiles(join(projectRoot, root), files);
|
|
230
|
+
}
|
|
231
|
+
const findings = [];
|
|
232
|
+
const inventory = {};
|
|
233
|
+
let filesScanned = 0;
|
|
234
|
+
for (const abs of files) {
|
|
235
|
+
const relPosix = toPosix(relative(projectRoot, abs));
|
|
236
|
+
if (!isProductionSource(relPosix) || relPosix === MUTATION_BOUNDARY_MODULE)
|
|
237
|
+
continue;
|
|
238
|
+
filesScanned += 1;
|
|
239
|
+
let text;
|
|
240
|
+
try {
|
|
241
|
+
text = readFileSync(abs, "utf8");
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
MUTATION_CALL_PATTERN.lastIndex = 0;
|
|
247
|
+
const mutationCalls = text.match(MUTATION_CALL_PATTERN)?.length ?? 0;
|
|
248
|
+
if (mutationCalls > 0)
|
|
249
|
+
inventory[relPosix] = mutationCalls;
|
|
250
|
+
const sections = mutationCalls > 0 ? extractMutationSections(text) : [];
|
|
251
|
+
const lines = text.split(/\r?\n/);
|
|
252
|
+
let offset = 0;
|
|
253
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
254
|
+
const line = lines[i] ?? "";
|
|
255
|
+
const lineStart = offset;
|
|
256
|
+
offset += line.length + 1;
|
|
257
|
+
const trimmed = line.trim();
|
|
258
|
+
if (isDeclarationLine(trimmed))
|
|
259
|
+
continue;
|
|
260
|
+
for (const rule of RAW_MUTATION_CALL_RULES) {
|
|
261
|
+
if (rule.pattern.test(line) && !rule.allowedFiles.includes(relPosix)) {
|
|
262
|
+
findings.push({ path: relPosix, line: i + 1, rule: rule.label, text: trimmed });
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// Inside a critical section the artifact identity is the captured one.
|
|
266
|
+
const insideSection = sections.some(([start, end]) => lineStart >= start && lineStart <= end);
|
|
267
|
+
if (insideSection && relPosix !== MUTATION_CAPABILITY_MODULE) {
|
|
268
|
+
for (const pattern of RESOLVER_CALL_PATTERNS) {
|
|
269
|
+
if (pattern.test(line)) {
|
|
270
|
+
findings.push({
|
|
271
|
+
path: relPosix,
|
|
272
|
+
line: i + 1,
|
|
273
|
+
rule: "artifact path re-resolved inside a mutation section",
|
|
274
|
+
text: trimmed,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return { findings, inventory, filesScanned };
|
|
282
|
+
}
|
|
283
|
+
/** Render findings as a stable, reviewable report. */
|
|
284
|
+
export function formatMutationBoundaryFindings(findings) {
|
|
285
|
+
return findings
|
|
286
|
+
.map((f) => ` ${f.path}:${f.line} [${f.rule}] ${f.text}`)
|
|
287
|
+
.sort()
|
|
288
|
+
.join("\n");
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* The fail-closed verdict: no bypass, and the mutation inventory still matches
|
|
292
|
+
* the recorded census. Adding or removing a mutation site is a deliberate edit
|
|
293
|
+
* to {@link PRODUCTION_MUTATION_INVENTORY} and the census constants above.
|
|
294
|
+
*/
|
|
295
|
+
export function evaluateProjectDefinitionMutationBoundary(projectRoot) {
|
|
296
|
+
const scan = scanProjectDefinitionMutationBoundary(projectRoot);
|
|
297
|
+
const errors = [];
|
|
298
|
+
if (scan.findings.length > 0) {
|
|
299
|
+
errors.push(`${scan.findings.length} raw resolver/lock/write bypass(es) outside the mutation capability:\n` +
|
|
300
|
+
formatMutationBoundaryFindings(scan.findings));
|
|
301
|
+
}
|
|
302
|
+
for (const [path, expected] of Object.entries(PRODUCTION_MUTATION_INVENTORY)) {
|
|
303
|
+
const actual = scan.inventory[path] ?? 0;
|
|
304
|
+
if (actual !== expected) {
|
|
305
|
+
errors.push(`${path}: expected ${expected} mutation call(s), found ${actual}`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
for (const path of Object.keys(scan.inventory)) {
|
|
309
|
+
if (!(path in PRODUCTION_MUTATION_INVENTORY)) {
|
|
310
|
+
errors.push(`${path}: mutation call site not in the recorded inventory`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
const total = Object.values(scan.inventory).reduce((sum, n) => sum + n, 0);
|
|
314
|
+
const expectedTotal = PREVIOUSLY_LOCKED_CORE_CALL_EXPRESSIONS +
|
|
315
|
+
PREVIOUSLY_UNLOCKED_CLI_WRITERS +
|
|
316
|
+
PARITY_HARNESS_CALL_EXPRESSIONS;
|
|
317
|
+
if (total !== expectedTotal) {
|
|
318
|
+
errors.push(`census total: expected ${expectedTotal} mutation call(s), found ${total}`);
|
|
319
|
+
}
|
|
320
|
+
const coreFiles = Object.keys(scan.inventory).filter((path) => path.startsWith("packages/core/") && !path.includes("parity-scenarios"));
|
|
321
|
+
if (coreFiles.length !== PREVIOUSLY_LOCKED_CORE_FILES) {
|
|
322
|
+
errors.push(`census files: expected ${PREVIOUSLY_LOCKED_CORE_FILES} core file(s), found ${coreFiles.length}`);
|
|
323
|
+
}
|
|
324
|
+
return { ok: errors.length === 0, errors, scan };
|
|
325
|
+
}
|
|
326
|
+
//# sourceMappingURL=project-definition-mutation-boundary.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C2 — semantic single-source conformance (#3600 / #3899).
|
|
3
|
+
*
|
|
4
|
+
* Shipped guidance must name one value where the framework has one value.
|
|
5
|
+
* The 0.6-versus-0.8 defect lives inside a file that resolves perfectly, so
|
|
6
|
+
* pointer existence (C1) cannot see it. This oracle is not a link checker.
|
|
7
|
+
*
|
|
8
|
+
* Evaluates a staged pack root (flattened consumer deposit) or a source
|
|
9
|
+
* checkout (content/ prefix + root main.md). Three-state: 0 clean / 1 drift / 2 config.
|
|
10
|
+
*/
|
|
11
|
+
/** Closed, typed current-authoring surfaces (#3600 AC / #3899 C2). */
|
|
12
|
+
export declare const C2_AUTHORING_SURFACES: readonly ["main.md", "skills/deft-directive-setup/SKILL.md", "skills/deft-directive-build/SKILL.md", "skills/deft-directive-interview/SKILL.md", "skills/deft-directive-refinement/SKILL.md", "skills/deft-directive-sync/SKILL.md", "templates/project.md.template", "templates/make-spec.md", "conventions/references.md", "commands.md"];
|
|
13
|
+
export type C2AuthoringSurface = (typeof C2_AUTHORING_SURFACES)[number];
|
|
14
|
+
export interface SemanticSingleSourceViolation {
|
|
15
|
+
readonly path: string;
|
|
16
|
+
readonly line: number;
|
|
17
|
+
readonly version: string;
|
|
18
|
+
readonly excerpt: string;
|
|
19
|
+
}
|
|
20
|
+
export interface SemanticSingleSourceResult {
|
|
21
|
+
readonly code: 0 | 1 | 2;
|
|
22
|
+
readonly message: string;
|
|
23
|
+
readonly stream: "stdout" | "stderr";
|
|
24
|
+
readonly setupWriteVersion: string | null;
|
|
25
|
+
readonly violations: readonly SemanticSingleSourceViolation[];
|
|
26
|
+
readonly currentWriteVersions: readonly string[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve a closed-list surface against a flattened pack root or a source
|
|
30
|
+
* checkout (content/ prefix for everything except root harness main.md).
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveAuthoringSurface(packRoot: string, rel: string): string | null;
|
|
33
|
+
export declare function extractQuotedVersions(line: string): string[];
|
|
34
|
+
export declare function extractSetupWriteVersion(setupText: string): string | null;
|
|
35
|
+
export declare function evaluateSemanticSingleSource(packRoot: string): SemanticSingleSourceResult;
|
|
36
|
+
//# sourceMappingURL=semantic-single-source.d.ts.map
|