@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.
Files changed (271) hide show
  1. package/dist/architecture/sor-preflight.js +2 -0
  2. package/dist/cache/operations.js +1 -1
  3. package/dist/check/cached-orchestrator.js +28 -3
  4. package/dist/check/gate-lists.d.ts +14 -0
  5. package/dist/check/gate-lists.js +26 -3
  6. package/dist/check/named-cause.js +18 -3
  7. package/dist/check/session-completed-ac.d.ts +1 -1
  8. package/dist/check/session-completed-ac.js +1 -1
  9. package/dist/codebase/provider.js +7 -1
  10. package/dist/consumer-check-contract/evaluate.d.ts +47 -0
  11. package/dist/consumer-check-contract/evaluate.js +181 -15
  12. package/dist/delivery-attempt/evaluate.d.ts +9 -1
  13. package/dist/delivery-attempt/evaluate.js +69 -0
  14. package/dist/delivery-attempt/handoff.js +1 -1
  15. package/dist/delivery-attempt/index.d.ts +1 -1
  16. package/dist/delivery-attempt/index.js +1 -1
  17. package/dist/deposit/live-procedure-exclusions.d.ts +18 -0
  18. package/dist/deposit/live-procedure-exclusions.js +110 -0
  19. package/dist/deposit/live-procedure-targets.d.ts +45 -0
  20. package/dist/deposit/live-procedure-targets.js +274 -0
  21. package/dist/deposit/python-free.d.ts +6 -0
  22. package/dist/deposit/python-free.js +15 -0
  23. package/dist/deposit/rewrite-deposit-links.d.ts +42 -0
  24. package/dist/deposit/rewrite-deposit-links.js +148 -0
  25. package/dist/deposit/run-stage-content-pack.d.ts +2 -0
  26. package/dist/deposit/run-stage-content-pack.js +3 -0
  27. package/dist/deposit/stage-content-pack.d.ts +17 -0
  28. package/dist/deposit/stage-content-pack.js +91 -0
  29. package/dist/design-critique/citation-grammar.d.ts +60 -0
  30. package/dist/design-critique/citation-grammar.js +303 -0
  31. package/dist/design-critique/completed-arc-record.d.ts +62 -0
  32. package/dist/design-critique/completed-arc-record.js +277 -0
  33. package/dist/freshness/bind.d.ts +32 -3
  34. package/dist/freshness/bind.js +58 -12
  35. package/dist/hooks/classify/host-session-identity.d.ts +89 -0
  36. package/dist/hooks/classify/host-session-identity.js +467 -0
  37. package/dist/hooks/classify/index.d.ts +3 -2
  38. package/dist/hooks/classify/index.js +3 -2
  39. package/dist/hooks/classify/paths.d.ts +9 -0
  40. package/dist/hooks/classify/paths.js +39 -0
  41. package/dist/hooks/classify/stdin.d.ts +5 -0
  42. package/dist/hooks/classify/stdin.js +94 -1
  43. package/dist/hooks/dest-form.d.ts +20 -1
  44. package/dist/hooks/dest-form.js +158 -21
  45. package/dist/hooks/dispatcher.d.ts +58 -3
  46. package/dist/hooks/dispatcher.js +762 -73
  47. package/dist/hooks/fixtures/cases.d.ts +22 -2
  48. package/dist/hooks/fixtures/cases.js +228 -0
  49. package/dist/hooks/git-destructive-log.d.ts +32 -0
  50. package/dist/hooks/git-destructive-log.js +46 -0
  51. package/dist/hooks/index.d.ts +2 -0
  52. package/dist/hooks/index.js +2 -0
  53. package/dist/hooks/scope.js +3 -1
  54. package/dist/hooks/shell-write-targets.d.ts +10 -0
  55. package/dist/hooks/shell-write-targets.js +274 -0
  56. package/dist/hooks/tools.d.ts +20 -2
  57. package/dist/hooks/tools.js +30 -1
  58. package/dist/init-deposit/agent-hooks.d.ts +2 -1
  59. package/dist/init-deposit/agent-hooks.js +8 -1
  60. package/dist/init-deposit/gitignore.d.ts +7 -0
  61. package/dist/init-deposit/gitignore.js +24 -0
  62. package/dist/init-deposit/hook-runtime-travel.d.ts +77 -0
  63. package/dist/init-deposit/hook-runtime-travel.js +269 -0
  64. package/dist/init-deposit/init-deposit.js +3 -0
  65. package/dist/init-deposit/refresh.js +7 -0
  66. package/dist/init-deposit/runtime-writers.d.ts +14 -0
  67. package/dist/init-deposit/runtime-writers.js +33 -0
  68. package/dist/intake/clause-derivation.js +9 -3
  69. package/dist/intake/issue-ingest.d.ts +6 -1
  70. package/dist/intake/issue-ingest.js +83 -4
  71. package/dist/intake/platform-capabilities.d.ts +9 -2
  72. package/dist/intake/platform-capabilities.js +38 -9
  73. package/dist/intake/reconcile-issues.js +13 -13
  74. package/dist/lifecycle/brief-envelope.d.ts +25 -0
  75. package/dist/lifecycle/brief-envelope.js +42 -0
  76. package/dist/lifecycle/index.d.ts +1 -0
  77. package/dist/lifecycle/index.js +1 -0
  78. package/dist/literal-acceptance/evaluate.js +14 -5
  79. package/dist/literal-acceptance/index.d.ts +1 -1
  80. package/dist/literal-acceptance/index.js +1 -1
  81. package/dist/literal-acceptance/run.d.ts +2 -0
  82. package/dist/literal-acceptance/run.js +19 -1
  83. package/dist/orphan-active/candidate-scope.d.ts +53 -0
  84. package/dist/orphan-active/candidate-scope.js +157 -0
  85. package/dist/orphan-active/evaluate.d.ts +52 -0
  86. package/dist/orphan-active/evaluate.js +250 -128
  87. package/dist/orphan-active/index.d.ts +2 -0
  88. package/dist/orphan-active/index.js +2 -0
  89. package/dist/orphan-active/issue-state.d.ts +121 -0
  90. package/dist/orphan-active/issue-state.js +278 -0
  91. package/dist/platform/cursor-managed-runtime.d.ts +95 -0
  92. package/dist/platform/cursor-managed-runtime.js +241 -0
  93. package/dist/platform/index.d.ts +1 -0
  94. package/dist/platform/index.js +1 -0
  95. package/dist/platform/platform-capabilities.d.ts +23 -1
  96. package/dist/platform/platform-capabilities.js +55 -15
  97. package/dist/policy/ceremony-dial.js +5 -9
  98. package/dist/policy/host-hooks.js +4 -9
  99. package/dist/policy/merge-approval-head.js +7 -6
  100. package/dist/policy/org-force-on-migration.js +5 -10
  101. package/dist/policy/plan-extensions.d.ts +14 -2
  102. package/dist/policy/plan-extensions.js +24 -3
  103. package/dist/policy/product-signal.js +5 -10
  104. package/dist/policy/require-human-merge.js +5 -9
  105. package/dist/policy/resolve.js +77 -16
  106. package/dist/policy/value-feedback.js +9 -18
  107. package/dist/pr-closeout-attestable/evaluate.d.ts +80 -0
  108. package/dist/pr-closeout-attestable/evaluate.js +306 -0
  109. package/dist/pr-closeout-attestable/index.d.ts +2 -0
  110. package/dist/pr-closeout-attestable/index.js +2 -0
  111. package/dist/pr-closing-keywords/gh.js +32 -9
  112. package/dist/pr-closing-keywords/main.d.ts +1 -0
  113. package/dist/pr-closing-keywords/main.js +68 -3
  114. package/dist/pr-closing-keywords/types.d.ts +2 -0
  115. package/dist/pr-merge-readiness/gh.js +32 -9
  116. package/dist/pr-protected-issues/gh.d.ts +6 -2
  117. package/dist/pr-protected-issues/gh.js +42 -11
  118. package/dist/pr-wait-mergeable/cascade.d.ts +9 -1
  119. package/dist/pr-wait-mergeable/cascade.js +21 -1
  120. package/dist/pr-wait-mergeable/types.d.ts +2 -0
  121. package/dist/pr-wait-mergeable/wrappers.d.ts +6 -0
  122. package/dist/pr-wait-mergeable/wrappers.js +14 -3
  123. package/dist/preflight/evaluate.d.ts +15 -0
  124. package/dist/preflight/evaluate.js +29 -3
  125. package/dist/product-first-done-gate/acceptance-resolver.d.ts +14 -2
  126. package/dist/product-first-done-gate/acceptance-resolver.js +13 -2
  127. package/dist/product-first-done-gate/evaluate.js +23 -9
  128. package/dist/product-first-done-gate/types.js +2 -0
  129. package/dist/release/cli-drift-report.d.ts +68 -0
  130. package/dist/release/cli-drift-report.js +189 -0
  131. package/dist/release/consumer-hard-stops.d.ts +48 -0
  132. package/dist/release/consumer-hard-stops.js +140 -0
  133. package/dist/release/consumer-readiness-disclosure.d.ts +18 -0
  134. package/dist/release/consumer-readiness-disclosure.js +51 -0
  135. package/dist/release/index.d.ts +3 -0
  136. package/dist/release/index.js +3 -0
  137. package/dist/release/issue-state-fetch.d.ts +5 -3
  138. package/dist/release/issue-state-fetch.js +86 -21
  139. package/dist/release/native-steps.js +1 -0
  140. package/dist/release/pipeline.js +74 -0
  141. package/dist/release/run-consumer-readiness.d.ts +15 -0
  142. package/dist/release/run-consumer-readiness.js +24 -0
  143. package/dist/release/types.d.ts +20 -0
  144. package/dist/render/constants.d.ts +4 -0
  145. package/dist/render/constants.js +11 -8
  146. package/dist/render/export-spec.js +31 -5
  147. package/dist/render/index.d.ts +1 -1
  148. package/dist/render/index.js +1 -1
  149. package/dist/render/prd-render.d.ts +4 -1
  150. package/dist/render/prd-render.js +82 -23
  151. package/dist/render/project-render.js +14 -7
  152. package/dist/render/scope-outlook.d.ts +2 -0
  153. package/dist/render/scope-outlook.js +3 -0
  154. package/dist/render/spec-render.js +2 -2
  155. package/dist/resolution/package-manager.d.ts +33 -4
  156. package/dist/resolution/package-manager.js +210 -9
  157. package/dist/review-monitor/constants.d.ts +7 -0
  158. package/dist/review-monitor/constants.js +7 -0
  159. package/dist/review-monitor/github-lease.d.ts +98 -1
  160. package/dist/review-monitor/github-lease.js +186 -4
  161. package/dist/review-monitor/lease-comment.d.ts +36 -0
  162. package/dist/review-monitor/lease-comment.js +103 -2
  163. package/dist/run-summary/types.d.ts +2 -2
  164. package/dist/scm/build-command.d.ts +2 -2
  165. package/dist/scm/build-command.js +2 -2
  166. package/dist/scm/call-shape.d.ts +25 -0
  167. package/dist/scm/call-shape.js +59 -0
  168. package/dist/scm/call.d.ts +7 -4
  169. package/dist/scm/call.js +48 -9
  170. package/dist/scm/design-critique-chip.d.ts +1 -0
  171. package/dist/scm/design-critique-chip.js +22 -6
  172. package/dist/scm/gh-rest.d.ts +34 -13
  173. package/dist/scm/gh-rest.js +168 -15
  174. package/dist/scm/index.d.ts +2 -0
  175. package/dist/scm/index.js +2 -0
  176. package/dist/scm/readiness.d.ts +2 -0
  177. package/dist/scm/readiness.js +28 -4
  178. package/dist/scm/spawn-status.d.ts +33 -0
  179. package/dist/scm/spawn-status.js +53 -0
  180. package/dist/scope/acceptance-evidence.d.ts +1 -1
  181. package/dist/scope/project-definition-sync.js +14 -7
  182. package/dist/scope/transition.js +4 -14
  183. package/dist/session/ac-pass-banking.d.ts +2 -2
  184. package/dist/session/ac-pass-banking.js +2 -2
  185. package/dist/session/git.d.ts +24 -0
  186. package/dist/session/git.js +138 -2
  187. package/dist/session/host-session-owner.d.ts +53 -0
  188. package/dist/session/host-session-owner.js +89 -0
  189. package/dist/session/index.d.ts +1 -0
  190. package/dist/session/index.js +1 -0
  191. package/dist/session/occupancy.d.ts +259 -13
  192. package/dist/session/occupancy.js +877 -33
  193. package/dist/session/ritual-sentinel.d.ts +5 -0
  194. package/dist/session/ritual-sentinel.js +5 -0
  195. package/dist/session/session-ready.d.ts +5 -1
  196. package/dist/session/session-ready.js +98 -8
  197. package/dist/session/session-start.d.ts +5 -1
  198. package/dist/session/session-start.js +32 -17
  199. package/dist/session/toolchain-preflight.d.ts +13 -3
  200. package/dist/session/toolchain-preflight.js +93 -18
  201. package/dist/session/verify-ac-session-cache.d.ts +2 -2
  202. package/dist/session/verify-ac-session-cache.js +2 -2
  203. package/dist/session/verify-session-ritual.d.ts +11 -0
  204. package/dist/session/verify-session-ritual.js +60 -15
  205. package/dist/slice/constants.d.ts +1 -1
  206. package/dist/spec-authority/constants.d.ts +10 -2
  207. package/dist/spec-authority/constants.js +53 -8
  208. package/dist/spec-authority/resolver.d.ts +3 -0
  209. package/dist/spec-authority/resolver.js +55 -7
  210. package/dist/subprocess/max-buffer.d.ts +14 -0
  211. package/dist/subprocess/max-buffer.js +15 -0
  212. package/dist/swarm/complete-cohort.d.ts +2 -0
  213. package/dist/swarm/complete-cohort.js +21 -13
  214. package/dist/swarm/index.d.ts +1 -0
  215. package/dist/swarm/index.js +1 -0
  216. package/dist/swarm/launch-cli.js +53 -33
  217. package/dist/swarm/launch.d.ts +8 -0
  218. package/dist/swarm/launch.js +63 -43
  219. package/dist/swarm/pre-dispatch-cli.js +2 -1
  220. package/dist/swarm/pre-dispatch.js +10 -1
  221. package/dist/swarm/subagent-status-dir.d.ts +27 -0
  222. package/dist/swarm/subagent-status-dir.js +42 -0
  223. package/dist/swarm/worktrees.d.ts +17 -3
  224. package/dist/swarm/worktrees.js +48 -4
  225. package/dist/triage/evaluate/worktrees.js +153 -6
  226. package/dist/triage/scope/mutations-core.d.ts +2 -6
  227. package/dist/triage/scope/mutations-core.js +23 -55
  228. package/dist/triage/scope-drift/add-ignore.js +5 -39
  229. package/dist/triage/subscribe/index.d.ts +2 -6
  230. package/dist/triage/subscribe/index.js +15 -65
  231. package/dist/triage/welcome/writers.js +15 -74
  232. package/dist/umbrella-current-shape/index.d.ts +51 -3
  233. package/dist/umbrella-current-shape/index.js +106 -18
  234. package/dist/validate-content/deposit-required.d.ts +39 -0
  235. package/dist/validate-content/deposit-required.js +147 -0
  236. package/dist/validate-content/index.d.ts +1 -0
  237. package/dist/validate-content/index.js +1 -0
  238. package/dist/validate-content/validate-links.d.ts +2 -3
  239. package/dist/validate-content/validate-links.js +29 -2
  240. package/dist/vbrief-activate/activate.d.ts +7 -2
  241. package/dist/vbrief-activate/activate.js +26 -13
  242. package/dist/vbrief-build/index.d.ts +2 -1
  243. package/dist/vbrief-build/index.js +2 -1
  244. package/dist/vbrief-build/parity-scenarios.js +5 -5
  245. package/dist/vbrief-build/project-definition-io.d.ts +63 -3
  246. package/dist/vbrief-build/project-definition-io.js +357 -31
  247. package/dist/vbrief-build/project-definition-mutation.d.ts +32 -0
  248. package/dist/vbrief-build/project-definition-mutation.js +43 -0
  249. package/dist/vbrief-validate/conformance.d.ts +1 -0
  250. package/dist/vbrief-validate/conformance.js +85 -8
  251. package/dist/vbrief-validate/main.js +2 -0
  252. package/dist/vbrief-validate/precutover.js +5 -10
  253. package/dist/verify-ac/clauses.d.ts +62 -2
  254. package/dist/verify-ac/clauses.js +183 -111
  255. package/dist/verify-ac/evaluate.d.ts +9 -0
  256. package/dist/verify-ac/evaluate.js +32 -9
  257. package/dist/verify-ac/index.d.ts +1 -1
  258. package/dist/verify-ac/index.js +1 -1
  259. package/dist/verify-env/node-runtime.d.ts +8 -4
  260. package/dist/verify-env/node-runtime.js +9 -6
  261. package/dist/verify-env/toolchain-check.d.ts +35 -3
  262. package/dist/verify-env/toolchain-check.js +155 -36
  263. package/dist/verify-source/deposit-closure.d.ts +23 -0
  264. package/dist/verify-source/deposit-closure.js +162 -0
  265. package/dist/verify-source/index.d.ts +2 -0
  266. package/dist/verify-source/index.js +2 -0
  267. package/dist/verify-source/project-definition-mutation-boundary.d.ts +104 -0
  268. package/dist/verify-source/project-definition-mutation-boundary.js +326 -0
  269. package/dist/verify-source/semantic-single-source.d.ts +36 -0
  270. package/dist/verify-source/semantic-single-source.js +349 -0
  271. package/package.json +7 -3
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Flatten-aware rewrite of relative markdown links from the source tree onto
3
+ * the C1 packed layout (#3937).
4
+ *
5
+ * Source checkout: content/X lives under content/; root main.md / SKILL.md stay
6
+ * at the repo root. Deposit: content/ children flatten to the payload root, and
7
+ * harness entries land beside them. A naive `./content/` strip cannot express
8
+ * the reverse `../../main.md` escape. This rewrite maps each relative target
9
+ * through the source path, then emits a deposit-relative href.
10
+ */
11
+ import { posix } from "node:path";
12
+ import { extractLinkTargets, shouldSkipLinkTarget } from "../validate-content/link-parser.js";
13
+ export const DEPOSIT_LINK_REWRITE_VERSION = "1";
14
+ export const REWRITE_MARKER_PREFIX = "<!-- deft:deposit-link-rewrite";
15
+ const HARNESS_PACK_FILES = new Set(["main.md", "SKILL.md", "Taskfile.yml"]);
16
+ export function isUrlLikeTarget(target) {
17
+ return (target.startsWith("http://") ||
18
+ target.startsWith("https://") ||
19
+ target.startsWith("mailto:") ||
20
+ target.startsWith("#"));
21
+ }
22
+ /** Map a repo-relative source path to its packed-deposit relative path. */
23
+ export function mapSourceToPackRelative(sourceRel) {
24
+ let n = sourceRel.replace(/\\/g, "/");
25
+ if (n.length > 1 && n.endsWith("/"))
26
+ n = n.slice(0, -1);
27
+ if (n === "." || n === "")
28
+ return ".";
29
+ if (HARNESS_PACK_FILES.has(n) || n.startsWith("tasks/") || n.startsWith(".githooks/")) {
30
+ return n;
31
+ }
32
+ if (n === "content")
33
+ return ".";
34
+ if (n.startsWith("content/"))
35
+ return n.slice("content/".length);
36
+ return null;
37
+ }
38
+ /** Inverse: packed path -> source path the file was copied from. */
39
+ export function sourceRelForPackRel(packRel) {
40
+ const n = packRel.replace(/\\/g, "/");
41
+ if (HARNESS_PACK_FILES.has(n) || n.startsWith("tasks/") || n.startsWith(".githooks/")) {
42
+ return n;
43
+ }
44
+ return `content/${n}`;
45
+ }
46
+ export function resolveSourceTargetRel(sourceFileRel, rawPath) {
47
+ const sourceDir = posix.dirname(sourceFileRel.replace(/\\/g, "/"));
48
+ return posix.normalize(posix.join(sourceDir, rawPath)).replace(/\\/g, "/");
49
+ }
50
+ export function splitLinkHash(target) {
51
+ const hash = target.indexOf("#");
52
+ const query = target.indexOf("?");
53
+ let cut = -1;
54
+ if (hash === -1)
55
+ cut = query;
56
+ else if (query === -1)
57
+ cut = hash;
58
+ else
59
+ cut = Math.min(hash, query);
60
+ if (cut === -1)
61
+ return { path: target, suffix: "" };
62
+ return { path: target.slice(0, cut), suffix: target.slice(cut) };
63
+ }
64
+ export function rewriteRelativeLink(options) {
65
+ const { sourceFileRel, packFileRel, target } = options;
66
+ if (isUrlLikeTarget(target) || shouldSkipLinkTarget(target)) {
67
+ return { next: target, rewritten: false, packMapped: true };
68
+ }
69
+ const { path: rawPath, suffix } = splitLinkHash(target);
70
+ if (!rawPath)
71
+ return { next: target, rewritten: false, packMapped: true };
72
+ const trailingSlash = rawPath.endsWith("/");
73
+ const sourceTarget = resolveSourceTargetRel(sourceFileRel, rawPath);
74
+ if (sourceTarget === ".." || sourceTarget.startsWith("../")) {
75
+ return { next: target, rewritten: false, packMapped: false };
76
+ }
77
+ const packTarget = mapSourceToPackRelative(sourceTarget);
78
+ if (packTarget === null) {
79
+ return { next: target, rewritten: false, packMapped: false };
80
+ }
81
+ const packDir = posix.dirname(packFileRel.replace(/\\/g, "/"));
82
+ let rel = posix.relative(packDir, packTarget).replace(/\\/g, "/");
83
+ if (rel === "")
84
+ rel = ".";
85
+ if (trailingSlash && rel !== "." && !rel.endsWith("/"))
86
+ rel = `${rel}/`;
87
+ if (rawPath.startsWith("./") && !rel.startsWith(".") && !rel.startsWith("/")) {
88
+ rel = `./${rel}`;
89
+ }
90
+ const next = `${rel}${suffix}`;
91
+ return { next, rewritten: next !== target, packMapped: true };
92
+ }
93
+ export function rewriteMarker(sourceRel) {
94
+ return `${REWRITE_MARKER_PREFIX} v=${DEPOSIT_LINK_REWRITE_VERSION} source="${sourceRel.replace(/\\/g, "/")}" -->`;
95
+ }
96
+ export function rewriteMarkdownDepositLinks(options) {
97
+ const lines = options.content.split("\n");
98
+ let rewriteCount = 0;
99
+ const out = [];
100
+ for (const line of lines) {
101
+ const targets = extractLinkTargets(line);
102
+ if (targets.length === 0) {
103
+ out.push(line);
104
+ continue;
105
+ }
106
+ let nextLine = line;
107
+ for (let i = targets.length - 1; i >= 0; i -= 1) {
108
+ const target = targets[i];
109
+ if (target === undefined)
110
+ continue;
111
+ const result = rewriteRelativeLink({
112
+ sourceFileRel: options.sourceFileRel,
113
+ packFileRel: options.packFileRel,
114
+ target,
115
+ });
116
+ if (!result.rewritten)
117
+ continue;
118
+ const needle = `](${target})`;
119
+ const at = nextLine.lastIndexOf(needle);
120
+ if (at === -1)
121
+ continue;
122
+ nextLine = `${nextLine.slice(0, at)}](${result.next})${nextLine.slice(at + needle.length)}`;
123
+ rewriteCount += 1;
124
+ }
125
+ out.push(nextLine);
126
+ }
127
+ if (rewriteCount === 0) {
128
+ return { content: options.content, rewriteCount: 0 };
129
+ }
130
+ let joined = out.join("\n");
131
+ if (!joined.includes(REWRITE_MARKER_PREFIX)) {
132
+ const marker = rewriteMarker(options.sourceFileRel);
133
+ if (joined.startsWith("<!--")) {
134
+ const end = joined.indexOf("-->");
135
+ if (end !== -1) {
136
+ joined = `${joined.slice(0, end + 3)}\n${marker}${joined.slice(end + 3)}`;
137
+ }
138
+ else {
139
+ joined = `${marker}\n${joined}`;
140
+ }
141
+ }
142
+ else {
143
+ joined = `${marker}\n${joined}`;
144
+ }
145
+ }
146
+ return { content: joined, rewriteCount };
147
+ }
148
+ //# sourceMappingURL=rewrite-deposit-links.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=run-stage-content-pack.d.ts.map
@@ -0,0 +1,3 @@
1
+ import { runPrepackFromContentPackage } from "./stage-content-pack.js";
2
+ runPrepackFromContentPackage(process.cwd());
3
+ //# sourceMappingURL=run-stage-content-pack.js.map
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Stage the @deftai/directive-content pack the same way prepack does, then
3
+ * rewrite relative markdown links onto the flattened deposit layout (#3937).
4
+ *
5
+ * Must not write into the source tree: destDir is the pack root (packages/content
6
+ * during prepack, or an out-of-tree temp dir in tests).
7
+ */
8
+ /** Copy content/ + harness + engine entries, then rewrite markdown links. */
9
+ export declare function stageContentPack(options: {
10
+ readonly repoRoot: string;
11
+ readonly destDir: string;
12
+ }): {
13
+ filesRewritten: number;
14
+ };
15
+ /** prepack cwd is packages/content. */
16
+ export declare function runPrepackFromContentPackage(pkgDir: string): void;
17
+ //# sourceMappingURL=stage-content-pack.d.ts.map
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Stage the @deftai/directive-content pack the same way prepack does, then
3
+ * rewrite relative markdown links onto the flattened deposit layout (#3937).
4
+ *
5
+ * Must not write into the source tree: destDir is the pack root (packages/content
6
+ * during prepack, or an out-of-tree temp dir in tests).
7
+ */
8
+ import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, } from "node:fs";
9
+ import { join, relative } from "node:path";
10
+ import { containedWrite } from "../fs/contained-write.js";
11
+ import { rewriteMarkdownDepositLinks, sourceRelForPackRel } from "./rewrite-deposit-links.js";
12
+ const ENGINE_ENTRIES = [".githooks", "Taskfile.yml", "tasks"];
13
+ const HARNESS_ENTRIES = ["main.md", "SKILL.md"];
14
+ function keepCopy(src) {
15
+ return !src.includes("__pycache__") && !src.endsWith(".pyc") && !src.endsWith(".py");
16
+ }
17
+ function rewriteStagedMarkdown(destDir) {
18
+ let filesRewritten = 0;
19
+ const walk = (dir) => {
20
+ let entries;
21
+ try {
22
+ entries = readdirSync(dir, { withFileTypes: true });
23
+ }
24
+ catch {
25
+ return;
26
+ }
27
+ for (const entry of entries) {
28
+ const full = join(dir, entry.name);
29
+ if (entry.isDirectory()) {
30
+ walk(full);
31
+ continue;
32
+ }
33
+ if (!entry.isFile() || !entry.name.endsWith(".md"))
34
+ continue;
35
+ const packRel = relative(destDir, full).replace(/\\/g, "/");
36
+ const original = readFileSync(full, "utf8");
37
+ const { content, rewriteCount } = rewriteMarkdownDepositLinks({
38
+ content: original,
39
+ sourceFileRel: sourceRelForPackRel(packRel),
40
+ packFileRel: packRel,
41
+ });
42
+ if (rewriteCount > 0 && content !== original) {
43
+ containedWrite({
44
+ root: destDir,
45
+ target: packRel,
46
+ data: content,
47
+ mode: "replace",
48
+ });
49
+ filesRewritten += 1;
50
+ }
51
+ }
52
+ };
53
+ walk(destDir);
54
+ return filesRewritten;
55
+ }
56
+ /** Copy content/ + harness + engine entries, then rewrite markdown links. */
57
+ export function stageContentPack(options) {
58
+ const { repoRoot, destDir } = options;
59
+ mkdirSync(destDir, { recursive: true });
60
+ const contentSrc = join(repoRoot, "content");
61
+ for (const name of readdirSync(contentSrc)) {
62
+ const from = join(contentSrc, name);
63
+ const to = join(destDir, name);
64
+ if (existsSync(to))
65
+ rmSync(to, { recursive: true, force: true });
66
+ cpSync(from, to, { recursive: true, filter: (src) => keepCopy(src) });
67
+ }
68
+ for (const name of ENGINE_ENTRIES) {
69
+ const from = join(repoRoot, name);
70
+ if (!existsSync(from))
71
+ continue;
72
+ const to = join(destDir, name);
73
+ if (existsSync(to))
74
+ rmSync(to, { recursive: true, force: true });
75
+ cpSync(from, to, { recursive: true, filter: (src) => keepCopy(src) });
76
+ }
77
+ for (const name of HARNESS_ENTRIES) {
78
+ const from = join(repoRoot, name);
79
+ if (!existsSync(from))
80
+ continue;
81
+ cpSync(from, join(destDir, name));
82
+ }
83
+ const filesRewritten = rewriteStagedMarkdown(destDir);
84
+ return { filesRewritten };
85
+ }
86
+ /** prepack cwd is packages/content. */
87
+ export function runPrepackFromContentPackage(pkgDir) {
88
+ const repoRoot = join(pkgDir, "..", "..");
89
+ stageContentPack({ repoRoot, destDir: pkgDir });
90
+ }
91
+ //# sourceMappingURL=stage-content-pack.js.map
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Citation grammar for the design-critique completed-arc record (#3831).
3
+ *
4
+ * One parser answers both questions the ingest predicate asks: which comment
5
+ * ids a synthesis cites, and whether it claims a verified-claims table. The
6
+ * closed accepted set and the refused positions are published in
7
+ * `content/contracts/design-critique.md` `## Citation grammar`; this module is
8
+ * the only implementation of that grammar.
9
+ *
10
+ * Which code-span convention governs. The intake cross-ref scanners
11
+ * (`intake/markdown-scanners.ts`) delete code spans, so for them a backticked
12
+ * id is an example and never a reference. The citation scan takes the opposite
13
+ * polarity for the id token only: a balanced single-backtick id is an accepted
14
+ * citation, because arc comments are hand-written prose and the mandated lean
15
+ * heading is itself `**Lean:**`. A keyword inside a code span or a fence stays
16
+ * an example in both layers. Positions are classified, never stripped -- the
17
+ * strippers delete a span with its contents, which destroys the digits. The
18
+ * prior art for classify-not-strip is `classifyHit`
19
+ * (`pr-closing-keywords/detect.ts`).
20
+ *
21
+ * The fence scan is local rather than borrowed from that detector because the
22
+ * detector's opener regex is anchored at column zero, so a CommonMark fence
23
+ * indented one to three spaces reads as prose. Relaxing it there would move
24
+ * hits into the #737 false-positive class and change what that gate suppresses,
25
+ * which is a separate decision from this one.
26
+ */
27
+ export type CitationKind = "lean" | "table" | "comment";
28
+ export type CitationRejectionClass = "code-fence" | "inline-code" | "blockquote" | "strikethrough" | "negation";
29
+ export type Citation = {
30
+ readonly id: number;
31
+ readonly kind: CitationKind;
32
+ };
33
+ export type RejectedCitation = {
34
+ readonly id: number;
35
+ readonly reason: CitationRejectionClass;
36
+ };
37
+ export type CitationScan = {
38
+ /** Accepted citations in document order, deduplicated on (id, kind). */
39
+ readonly citations: readonly Citation[];
40
+ /** Keyword-anchored or permalink occurrences refused by position. */
41
+ readonly rejected: readonly RejectedCitation[];
42
+ /** Every 8-or-more digit run in the body, for deterministic diagnostics. */
43
+ readonly idShapedRuns: readonly number[];
44
+ };
45
+ /** The published closed set, in the order the contract lists it. */
46
+ export declare const ACCEPTED_CITATION_FORMS: readonly string[];
47
+ /**
48
+ * Refused positions are exactly the five published classes. An indented code
49
+ * block and an HTML comment are deliberately not classified: a four-space
50
+ * indent is also ordinary list-continuation content, so refusing it would block
51
+ * valid records more often than it would catch example text.
52
+ */
53
+ export declare function classifyPosition(body: string, offset: number): CitationRejectionClass | null;
54
+ /**
55
+ * Parse the closed citation grammar out of one comment body. Refused positions
56
+ * are reported rather than dropped so a block detail can echo the observation
57
+ * instead of guessing at a cause.
58
+ */
59
+ export declare function scanCitations(body: string): CitationScan;
60
+ //# sourceMappingURL=citation-grammar.d.ts.map
@@ -0,0 +1,303 @@
1
+ /**
2
+ * Citation grammar for the design-critique completed-arc record (#3831).
3
+ *
4
+ * One parser answers both questions the ingest predicate asks: which comment
5
+ * ids a synthesis cites, and whether it claims a verified-claims table. The
6
+ * closed accepted set and the refused positions are published in
7
+ * `content/contracts/design-critique.md` `## Citation grammar`; this module is
8
+ * the only implementation of that grammar.
9
+ *
10
+ * Which code-span convention governs. The intake cross-ref scanners
11
+ * (`intake/markdown-scanners.ts`) delete code spans, so for them a backticked
12
+ * id is an example and never a reference. The citation scan takes the opposite
13
+ * polarity for the id token only: a balanced single-backtick id is an accepted
14
+ * citation, because arc comments are hand-written prose and the mandated lean
15
+ * heading is itself `**Lean:**`. A keyword inside a code span or a fence stays
16
+ * an example in both layers. Positions are classified, never stripped -- the
17
+ * strippers delete a span with its contents, which destroys the digits. The
18
+ * prior art for classify-not-strip is `classifyHit`
19
+ * (`pr-closing-keywords/detect.ts`).
20
+ *
21
+ * The fence scan is local rather than borrowed from that detector because the
22
+ * detector's opener regex is anchored at column zero, so a CommonMark fence
23
+ * indented one to three spaces reads as prose. Relaxing it there would move
24
+ * hits into the #737 false-positive class and change what that gate suppresses,
25
+ * which is a separate decision from this one.
26
+ */
27
+ /** The published closed set, in the order the contract lists it. */
28
+ export const ACCEPTED_CITATION_FORMS = [
29
+ "successor lean 12345678",
30
+ "successor lean: 12345678",
31
+ "successor lean `12345678`",
32
+ "**successor lean:** 12345678",
33
+ "#issuecomment-12345678",
34
+ "/issues/comments/12345678",
35
+ ];
36
+ const EMPHASIS = "(?:\\*\\*|\\*)";
37
+ const KEYWORD = "(successor[ \\t]+lean|verified-claims[ \\t]+table|lean|comment)";
38
+ /**
39
+ * Colon and horizontal whitespace only. One of the three branches must consume
40
+ * a colon or a space, so `lean12345678` is not a citation.
41
+ */
42
+ const SEPARATOR = `(?::${EMPHASIS}?[ \\t]*|${EMPHASIS}:?[ \\t]+|[ \\t]+)`;
43
+ /** Bare decimal, or a balanced single-backtick decimal. Nothing else. */
44
+ const ID_TOKEN = "(?:`(\\d{8,})`|(\\d{8,})\\b)";
45
+ const CITATION_RE = new RegExp(`${EMPHASIS}?\\b${KEYWORD}${SEPARATOR}${ID_TOKEN}` +
46
+ "|#issuecomment-(\\d{8,})" +
47
+ "|/issues/comments/(\\d{8,})", "gi");
48
+ const ID_RUN_RE = /\d{8,}/g;
49
+ const BLOCKQUOTE_RE = /^ {0,3}>/;
50
+ /** CommonMark fence delimiter: up to three leading spaces, the run, then the rest. */
51
+ const FENCE_LINE_RE = /^ {0,3}(`{3,}|~{3,})(.*)$/;
52
+ /** The last sentence break in a slice, and everything after it. */
53
+ const LAST_SENTENCE_RE = /[.!?;][^.!?;]*$/;
54
+ /** Everything up to the first sentence break. */
55
+ const FIRST_SENTENCE_RE = /^[^.!?;]*/;
56
+ /** The closed set of explicit negation markers the class recognises. */
57
+ const NEGATION_MARKER = "\\b(?:cannot|never|no longer" +
58
+ "|(?:do|does|did|is|are|was|were|has|have|had|will|would|shall|should|must|can|could|may|might)\\s+not" +
59
+ "|(?:do|does|did|is|are|was|were|has|have|had|wo|would|should|must|ca|could|sha)n['\\u2019]t)\\b";
60
+ /**
61
+ * Explicit negation of the citation itself, ending within three plain words of
62
+ * the keyword. A bare marker anywhere in the sentence prefix is not enough: it
63
+ * reads `without a doubt, successor lean N is accepted` and `not only successor
64
+ * lean N but also the table` as refusals, which blocks a valid record.
65
+ */
66
+ const NEGATED_CITATION_RE = new RegExp(`${NEGATION_MARKER}(?:\\s+[A-Za-z][A-Za-z'\\u2019-]*){0,3}\\s*$`, "i");
67
+ /** The same markers, unanchored, for the complement clause after a citation. */
68
+ const NEGATION_ANYWHERE_RE = new RegExp(NEGATION_MARKER, "i");
69
+ /**
70
+ * A negated verb of denial affirms the citation rather than refusing it, so the
71
+ * negation belongs to the verb and not to the occurrence: `we cannot deny that
72
+ * successor lean N binds` cites N. The verb set is closed and published --
73
+ * negating `deny`, `doubt`, `dispute`, `contest`, or `question` affirms the
74
+ * complement clause those verbs introduce.
75
+ *
76
+ * A trailing `that` alone is not the signal, because `that` is also a
77
+ * determiner. `do not use that successor lean N` and the cleft `the record is
78
+ * not that successor lean N` are genuine refusals, and both keep the negation
79
+ * class. The anchor is the end of the sentence segment, so a second negation
80
+ * before the keyword still binds: `we do not doubt that this does not bind
81
+ * successor lean N` is refused.
82
+ *
83
+ * The carve-out only suspends a prefix rule that already fired; it never
84
+ * refuses on its own, so it cannot widen the refused set. It also does not
85
+ * accept the citation outright. The complement clause is what carries the
86
+ * claim, so a negation anywhere in the rest of that sentence keeps the refusal:
87
+ * `we do not doubt that successor lean N does not bind` says the lean does not
88
+ * bind. That scan runs to the sentence break rather than to a clause boundary,
89
+ * which refuses more than it strictly must inside this one carve-out -- the
90
+ * fail-closed direction, and every such body was already refused before it.
91
+ */
92
+ const DENIAL_COMPLEMENT_RE = /\b(?:den(?:y|ies|ied|ying)|doubt(?:s|ed|ing)?|disput(?:e|es|ed|ing)|contest(?:s|ed|ing)?|question(?:s|ed|ing)?)\s+that\s*$/i;
93
+ function kindForKeyword(keyword) {
94
+ if (keyword === undefined)
95
+ return "comment";
96
+ const normalized = keyword.toLowerCase().replace(/[ \t]+/g, " ");
97
+ if (normalized.startsWith("verified-claims"))
98
+ return "table";
99
+ if (normalized === "comment")
100
+ return "comment";
101
+ return "lean";
102
+ }
103
+ function lineBounds(text, offset) {
104
+ const start = text.lastIndexOf("\n", offset - 1) + 1;
105
+ const found = text.indexOf("\n", offset);
106
+ return { start, end: found === -1 ? text.length : found };
107
+ }
108
+ /**
109
+ * CommonMark inline code: a run of N backticks opens a span that only a run of
110
+ * exactly N backticks closes. Counting single backticks would read a
111
+ * double-backtick span as balanced and let documentation prose cite.
112
+ *
113
+ * `text` is the whole span from the enclosing block start, not one line: a code
114
+ * span may carry a newline, so a line-scoped count cannot see the opener.
115
+ */
116
+ function isInsideInlineCode(text) {
117
+ let openRun = 0;
118
+ let i = 0;
119
+ while (i < text.length) {
120
+ if (text[i] !== "`") {
121
+ i += 1;
122
+ continue;
123
+ }
124
+ let run = 0;
125
+ while (i + run < text.length && text[i + run] === "`")
126
+ run += 1;
127
+ if (openRun === 0) {
128
+ openRun = run;
129
+ }
130
+ else if (run === openRun) {
131
+ openRun = 0;
132
+ }
133
+ i += run;
134
+ }
135
+ return openRun !== 0;
136
+ }
137
+ function isStruckThrough(text) {
138
+ let runs = 0;
139
+ let i = 0;
140
+ while (i < text.length - 1) {
141
+ if (text[i] === "~" && text[i + 1] === "~") {
142
+ runs += 1;
143
+ i += 2;
144
+ continue;
145
+ }
146
+ i += 1;
147
+ }
148
+ return runs % 2 === 1;
149
+ }
150
+ /**
151
+ * A negation binds the sentence it sits in, not the whole line. Scoping to the
152
+ * text after the last sentence break keeps `this is not stale. Bound contract
153
+ * is successor lean N` an affirmative citation.
154
+ */
155
+ function isNegated(line, column) {
156
+ const before = line.slice(0, column);
157
+ const tail = LAST_SENTENCE_RE.exec(before);
158
+ const segment = tail === null ? before : before.slice(tail.index + 1);
159
+ if (!NEGATED_CITATION_RE.test(segment))
160
+ return false;
161
+ if (!DENIAL_COMPLEMENT_RE.test(segment))
162
+ return true;
163
+ const after = line.slice(column);
164
+ return NEGATION_ANYWHERE_RE.test(FIRST_SENTENCE_RE.exec(after)?.[0] ?? after);
165
+ }
166
+ function fenceDelimiter(line) {
167
+ const match = FENCE_LINE_RE.exec(line);
168
+ if (match === null)
169
+ return null;
170
+ const run = match[1] ?? "";
171
+ const info = match[2] ?? "";
172
+ const char = run.startsWith("~") ? "~" : "`";
173
+ // A backtick opener's info string may not contain a backtick.
174
+ if (char === "`" && info.includes("`"))
175
+ return null;
176
+ return { char, len: run.length, info };
177
+ }
178
+ /**
179
+ * Walk the lines up to `offset` once and record both block facts the classifier
180
+ * needs. The fence stack follows CommonMark: opener and closer share the
181
+ * character, the closer is at least as long, and a closer carries no info
182
+ * string, so `` ```ts more text `` inside an open fence is content and not a
183
+ * closer. Inline scanning restarts after a blank line or a fence delimiter
184
+ * because neither a code span nor a strikethrough run crosses one. A blockquote
185
+ * marker carries forward to the blank line that ends the quote, so an unmarked
186
+ * lazy-continuation line is still quoted text.
187
+ *
188
+ * A fence delimiter also ends the quote block, and a line inside an open fence
189
+ * never opens one: a `>` in a fenced example is example text, so the marker must
190
+ * not survive the closing fence and refuse the citation that follows it. Lazy
191
+ * continuation is a paragraph rule, and a fence line is not paragraph text. A
192
+ * fence marked by `>` on every line is not a fence here -- `fenceDelimiter`
193
+ * requires the run at the line start -- so the line-level blockquote test still
194
+ * refuses a citation inside a blockquoted fence.
195
+ */
196
+ function blockPosition(body, offset) {
197
+ let open = null;
198
+ let inlineStart = 0;
199
+ let quotedBlock = false;
200
+ let lineStart = 0;
201
+ while (lineStart < offset) {
202
+ let lineEnd = body.indexOf("\n", lineStart);
203
+ const partial = lineEnd === -1 || lineEnd > offset;
204
+ if (partial) {
205
+ lineEnd = Math.min(body.length, offset);
206
+ }
207
+ const line = body.slice(lineStart, lineEnd);
208
+ const fence = fenceDelimiter(line);
209
+ if (fence !== null) {
210
+ if (open === null) {
211
+ open = fence;
212
+ }
213
+ else if (fence.char === open.char &&
214
+ fence.len >= open.len &&
215
+ fence.info.trim().length === 0) {
216
+ open = null;
217
+ }
218
+ }
219
+ if (!partial) {
220
+ const blank = line.trim().length === 0;
221
+ if (blank || fence !== null) {
222
+ inlineStart = lineEnd + 1;
223
+ quotedBlock = false;
224
+ }
225
+ else if (open === null && BLOCKQUOTE_RE.test(line)) {
226
+ quotedBlock = true;
227
+ }
228
+ }
229
+ if (lineEnd >= offset) {
230
+ break;
231
+ }
232
+ lineStart = lineEnd + 1;
233
+ }
234
+ return { insideFence: open !== null, inlineStart, quotedBlock };
235
+ }
236
+ /**
237
+ * Refused positions are exactly the five published classes. An indented code
238
+ * block and an HTML comment are deliberately not classified: a four-space
239
+ * indent is also ordinary list-continuation content, so refusing it would block
240
+ * valid records more often than it would catch example text.
241
+ */
242
+ export function classifyPosition(body, offset) {
243
+ const block = blockPosition(body, offset);
244
+ if (block.insideFence)
245
+ return "code-fence";
246
+ const { start, end } = lineBounds(body, offset);
247
+ const line = body.slice(start, end);
248
+ if (BLOCKQUOTE_RE.test(line) || block.quotedBlock)
249
+ return "blockquote";
250
+ const preceding = body.slice(block.inlineStart, offset);
251
+ if (isInsideInlineCode(preceding))
252
+ return "inline-code";
253
+ if (isStruckThrough(preceding))
254
+ return "strikethrough";
255
+ if (isNegated(line, offset - start))
256
+ return "negation";
257
+ return null;
258
+ }
259
+ function idShapedRuns(body) {
260
+ const runs = [];
261
+ const seen = new Set();
262
+ const re = new RegExp(ID_RUN_RE.source, ID_RUN_RE.flags);
263
+ for (const match of body.matchAll(re)) {
264
+ const id = Number(match[0]);
265
+ if (!Number.isSafeInteger(id) || id <= 0 || seen.has(id))
266
+ continue;
267
+ seen.add(id);
268
+ runs.push(id);
269
+ }
270
+ return runs;
271
+ }
272
+ /**
273
+ * Parse the closed citation grammar out of one comment body. Refused positions
274
+ * are reported rather than dropped so a block detail can echo the observation
275
+ * instead of guessing at a cause.
276
+ */
277
+ export function scanCitations(body) {
278
+ const citations = [];
279
+ const rejected = [];
280
+ const seen = new Set();
281
+ const re = new RegExp(CITATION_RE.source, CITATION_RE.flags);
282
+ for (const match of body.matchAll(re)) {
283
+ const raw = match[2] ?? match[3] ?? match[4] ?? match[5];
284
+ if (raw === undefined)
285
+ continue;
286
+ const id = Number(raw);
287
+ if (!Number.isSafeInteger(id) || id <= 0)
288
+ continue;
289
+ const reason = classifyPosition(body, match.index ?? 0);
290
+ if (reason !== null) {
291
+ rejected.push({ id, reason });
292
+ continue;
293
+ }
294
+ const kind = kindForKeyword(match[1]);
295
+ const key = `${id}|${kind}`;
296
+ if (seen.has(key))
297
+ continue;
298
+ seen.add(key);
299
+ citations.push({ id, kind });
300
+ }
301
+ return { citations, rejected, idShapedRuns: idShapedRuns(body) };
302
+ }
303
+ //# sourceMappingURL=citation-grammar.js.map