@deftai/directive-core 0.104.0 → 0.106.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 (287) hide show
  1. package/dist/authz/classify.js +1108 -67
  2. package/dist/check/cached-orchestrator.d.ts +1 -1
  3. package/dist/check/cached-orchestrator.js +2 -2
  4. package/dist/check/named-cause.d.ts +1 -1
  5. package/dist/check/named-cause.js +34 -4
  6. package/dist/codebase/default-extractor.d.ts +5 -0
  7. package/dist/codebase/default-extractor.js +7 -15
  8. package/dist/deposit/copy-tree.js +60 -0
  9. package/dist/deposit/python-free.js +26 -18
  10. package/dist/doctor/checks.d.ts +8 -0
  11. package/dist/doctor/checks.js +37 -25
  12. package/dist/doctor/doctor-state.d.ts +4 -0
  13. package/dist/doctor/doctor-state.js +7 -1
  14. package/dist/doctor/main.js +9 -19
  15. package/dist/doctor/types.d.ts +9 -0
  16. package/dist/forward-coverage/diff-coverage.d.ts +39 -0
  17. package/dist/forward-coverage/diff-coverage.js +112 -0
  18. package/dist/forward-coverage/diff-lines.d.ts +19 -0
  19. package/dist/forward-coverage/diff-lines.js +173 -0
  20. package/dist/forward-coverage/evaluate.d.ts +24 -9
  21. package/dist/forward-coverage/evaluate.js +125 -19
  22. package/dist/fs/contained-write.d.ts +115 -1
  23. package/dist/fs/contained-write.js +241 -5
  24. package/dist/fs/mutation-ledger.d.ts +54 -0
  25. package/dist/fs/mutation-ledger.js +133 -0
  26. package/dist/fs/non-product-dirs.d.ts +79 -0
  27. package/dist/fs/non-product-dirs.js +96 -0
  28. package/dist/hooks/dispatcher.d.ts +3 -1
  29. package/dist/hooks/dispatcher.js +14 -0
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.js +2 -0
  32. package/dist/init-deposit/agent-hooks.d.ts +1 -1
  33. package/dist/init-deposit/agent-hooks.js +18 -16
  34. package/dist/init-deposit/core-guard-pin-content.d.ts +7 -0
  35. package/dist/init-deposit/core-guard-pin-content.js +393 -0
  36. package/dist/init-deposit/gitignore.js +9 -0
  37. package/dist/init-deposit/hygiene.d.ts +47 -11
  38. package/dist/init-deposit/hygiene.js +172 -37
  39. package/dist/init-deposit/legacy-detect.js +6 -2
  40. package/dist/init-deposit/refresh.d.ts +21 -1
  41. package/dist/init-deposit/refresh.js +106 -9
  42. package/dist/init-deposit/scaffold.js +28 -279
  43. package/dist/init-deposit/slash-deposit.js +13 -7
  44. package/dist/init-deposit/xbrief-projections.d.ts +8 -1
  45. package/dist/init-deposit/xbrief-projections.js +24 -11
  46. package/dist/intake/clause-derivation.d.ts +47 -1
  47. package/dist/intake/clause-derivation.js +238 -9
  48. package/dist/intake/issue-ingest.d.ts +3 -1
  49. package/dist/intake/issue-ingest.js +35 -6
  50. package/dist/lifecycle/completed-tracked-on-delivery.d.ts +5 -0
  51. package/dist/lifecycle/completed-tracked-on-delivery.js +85 -18
  52. package/dist/lifecycle-visible/evaluate.d.ts +98 -0
  53. package/dist/lifecycle-visible/evaluate.js +710 -0
  54. package/dist/lifecycle-visible/index.d.ts +2 -0
  55. package/dist/lifecycle-visible/index.js +2 -0
  56. package/dist/literal-acceptance/capture.d.ts +10 -0
  57. package/dist/literal-acceptance/capture.js +226 -77
  58. package/dist/literal-acceptance/evaluate.d.ts +29 -4
  59. package/dist/literal-acceptance/evaluate.js +70 -2
  60. package/dist/literal-acceptance/index.d.ts +3 -3
  61. package/dist/literal-acceptance/index.js +3 -3
  62. package/dist/literal-acceptance/safety.d.ts +41 -0
  63. package/dist/literal-acceptance/safety.js +126 -2
  64. package/dist/literal-acceptance/types.d.ts +8 -0
  65. package/dist/orchestration/judgment-policy.d.ts +13 -0
  66. package/dist/orchestration/judgment-policy.js +15 -0
  67. package/dist/orchestration/probe-session.js +13 -8
  68. package/dist/orchestration/verify-judgment-gates.d.ts +4 -0
  69. package/dist/orchestration/verify-judgment-gates.js +43 -11
  70. package/dist/orphan-active/evaluate.d.ts +7 -1
  71. package/dist/orphan-active/evaluate.js +102 -23
  72. package/dist/platform/platform-capabilities.js +2 -3
  73. package/dist/policy/base-branch.d.ts +37 -0
  74. package/dist/policy/base-branch.js +114 -0
  75. package/dist/policy/branch-sync.d.ts +80 -0
  76. package/dist/policy/branch-sync.js +211 -0
  77. package/dist/policy/ceremony-dial-escalation.js +1 -0
  78. package/dist/policy/ceremony-dial.js +11 -21
  79. package/dist/policy/delivery-branch.d.ts +5 -3
  80. package/dist/policy/delivery-branch.js +7 -3
  81. package/dist/policy/file-size-thresholds.d.ts +24 -0
  82. package/dist/policy/file-size-thresholds.js +23 -0
  83. package/dist/policy/forge-outage-retry.d.ts +47 -0
  84. package/dist/policy/forge-outage-retry.js +157 -0
  85. package/dist/policy/host-hooks.d.ts +20 -0
  86. package/dist/policy/host-hooks.js +121 -2
  87. package/dist/policy/index.d.ts +7 -0
  88. package/dist/policy/index.js +66 -7
  89. package/dist/policy/org-force-on-migration.js +2 -1
  90. package/dist/policy/plan-extensions.d.ts +1 -1
  91. package/dist/policy/plan-extensions.js +2 -0
  92. package/dist/policy/product-signal.js +6 -7
  93. package/dist/policy/project-invariants.d.ts +50 -0
  94. package/dist/policy/project-invariants.js +205 -0
  95. package/dist/policy/require-human-merge.js +8 -6
  96. package/dist/policy/resolve.d.ts +7 -2
  97. package/dist/policy/resolve.js +25 -8
  98. package/dist/policy/sync-default.d.ts +129 -0
  99. package/dist/policy/sync-default.js +452 -0
  100. package/dist/policy/sync-max-files.d.ts +93 -0
  101. package/dist/policy/sync-max-files.js +192 -0
  102. package/dist/policy/value-feedback.js +7 -8
  103. package/dist/pr-monitor/absent-required.d.ts +11 -0
  104. package/dist/pr-monitor/absent-required.js +61 -0
  105. package/dist/pr-monitor/constants.d.ts +7 -0
  106. package/dist/pr-monitor/constants.js +7 -0
  107. package/dist/pr-monitor/index.d.ts +2 -1
  108. package/dist/pr-monitor/index.js +2 -1
  109. package/dist/pr-monitor/main.js +4 -0
  110. package/dist/pr-monitor/monitor.js +24 -1
  111. package/dist/pr-wait-mergeable/classify.js +6 -0
  112. package/dist/preflight/evaluate.d.ts +4 -0
  113. package/dist/preflight/evaluate.js +35 -1
  114. package/dist/preflight/index.d.ts +4 -0
  115. package/dist/preflight/index.js +2 -0
  116. package/dist/preflight/intended-placement.d.ts +62 -0
  117. package/dist/preflight/intended-placement.js +275 -0
  118. package/dist/preflight/project-invariants-gate.d.ts +29 -0
  119. package/dist/preflight/project-invariants-gate.js +82 -0
  120. package/dist/preflight-cache/evaluate.d.ts +12 -0
  121. package/dist/preflight-cache/evaluate.js +15 -1
  122. package/dist/preflight-cache/index.d.ts +1 -1
  123. package/dist/preflight-cache/index.js +1 -1
  124. package/dist/product-first-done-gate/acceptance-resolver.d.ts +128 -0
  125. package/dist/product-first-done-gate/acceptance-resolver.js +144 -0
  126. package/dist/product-first-done-gate/acceptance.d.ts +7 -4
  127. package/dist/product-first-done-gate/acceptance.js +79 -8
  128. package/dist/product-first-done-gate/empty-resolution.d.ts +4 -1
  129. package/dist/product-first-done-gate/empty-resolution.js +12 -1
  130. package/dist/product-first-done-gate/evaluate.d.ts +16 -0
  131. package/dist/product-first-done-gate/evaluate.js +298 -34
  132. package/dist/product-first-done-gate/index.d.ts +2 -0
  133. package/dist/product-first-done-gate/index.js +1 -0
  134. package/dist/release/build-dist.d.ts +101 -0
  135. package/dist/release/build-dist.js +428 -46
  136. package/dist/release/closed-verb-gate.d.ts +12 -0
  137. package/dist/release/closed-verb-gate.js +51 -0
  138. package/dist/release/index.d.ts +1 -0
  139. package/dist/release/index.js +1 -0
  140. package/dist/release/pipeline.js +7 -0
  141. package/dist/release/types.d.ts +12 -0
  142. package/dist/render/constants.d.ts +2 -1
  143. package/dist/render/constants.js +2 -1
  144. package/dist/render/framework-commands.js +4 -0
  145. package/dist/render/spec-validate.js +23 -12
  146. package/dist/run-summary/emit.d.ts +16 -10
  147. package/dist/run-summary/emit.js +26 -15
  148. package/dist/run-summary/index.d.ts +3 -2
  149. package/dist/run-summary/index.js +2 -1
  150. package/dist/run-summary/session-id.d.ts +21 -0
  151. package/dist/run-summary/session-id.js +92 -0
  152. package/dist/run-summary/types.d.ts +33 -4
  153. package/dist/run-summary/types.js +1 -0
  154. package/dist/scope/acceptance-evidence.d.ts +19 -7
  155. package/dist/scope/acceptance-evidence.js +38 -11
  156. package/dist/scope/delivery-evidence.d.ts +3 -3
  157. package/dist/scope/delivery-evidence.js +22 -27
  158. package/dist/scope/index.d.ts +1 -0
  159. package/dist/scope/index.js +1 -0
  160. package/dist/scope/main.js +15 -5
  161. package/dist/scope/parent-lineage.js +7 -6
  162. package/dist/scope/project-invariant-coverage.d.ts +54 -0
  163. package/dist/scope/project-invariant-coverage.js +322 -0
  164. package/dist/scope/promote-from-issue.js +5 -5
  165. package/dist/scope/transition.js +1 -1
  166. package/dist/scope-provenance/compare-intent.d.ts +27 -0
  167. package/dist/scope-provenance/compare-intent.js +233 -0
  168. package/dist/scope-provenance/digest.d.ts +18 -1
  169. package/dist/scope-provenance/digest.js +16 -11
  170. package/dist/scope-provenance/evaluate.d.ts +5 -1
  171. package/dist/scope-provenance/evaluate.js +67 -7
  172. package/dist/scope-provenance/extract-intent.d.ts +43 -0
  173. package/dist/scope-provenance/extract-intent.js +262 -0
  174. package/dist/scope-provenance/index.d.ts +7 -1
  175. package/dist/scope-provenance/index.js +7 -1
  176. package/dist/scope-provenance/intent-digest.d.ts +12 -0
  177. package/dist/scope-provenance/intent-digest.js +33 -0
  178. package/dist/scope-provenance/intent-evaluate.d.ts +43 -0
  179. package/dist/scope-provenance/intent-evaluate.js +149 -0
  180. package/dist/scope-provenance/json-tokenizer.d.ts +19 -0
  181. package/dist/scope-provenance/json-tokenizer.js +225 -0
  182. package/dist/scope-provenance/known-machine.d.ts +38 -0
  183. package/dist/scope-provenance/known-machine.js +157 -0
  184. package/dist/scope-provenance/mint-artifacts.d.ts +102 -0
  185. package/dist/scope-provenance/mint-artifacts.js +425 -0
  186. package/dist/session/ac-pass-banking.d.ts +9 -36
  187. package/dist/session/ac-pass-banking.js +33 -79
  188. package/dist/session/ac-pass-reuse.d.ts +53 -0
  189. package/dist/session/ac-pass-reuse.js +95 -0
  190. package/dist/session/git.js +19 -4
  191. package/dist/session/index.d.ts +4 -0
  192. package/dist/session/index.js +4 -0
  193. package/dist/session/occupancy-stress-worker.d.ts +7 -0
  194. package/dist/session/occupancy-stress-worker.js +36 -0
  195. package/dist/session/occupancy.d.ts +97 -0
  196. package/dist/session/occupancy.js +422 -0
  197. package/dist/session/openclaw-soft-rebind-deposit.js +6 -6
  198. package/dist/session/process-cost.d.ts +32 -10
  199. package/dist/session/process-cost.js +189 -1
  200. package/dist/session/product-state-hash.d.ts +26 -0
  201. package/dist/session/product-state-hash.js +700 -0
  202. package/dist/session/ritual-entrypoint.js +16 -1
  203. package/dist/session/session-ready.d.ts +2 -0
  204. package/dist/session/session-ready.js +52 -30
  205. package/dist/session/session-start.d.ts +13 -0
  206. package/dist/session/session-start.js +103 -9
  207. package/dist/session/verify-ac-session-cache.d.ts +42 -0
  208. package/dist/session/verify-ac-session-cache.js +126 -0
  209. package/dist/session/verify-session-ritual.d.ts +28 -0
  210. package/dist/session/verify-session-ritual.js +97 -5
  211. package/dist/slash/openclaw-deposit.js +13 -9
  212. package/dist/slice/constants.d.ts +2 -2
  213. package/dist/slice/constants.js +2 -2
  214. package/dist/slice/existing.js +9 -3
  215. package/dist/slice/lock.d.ts +16 -1
  216. package/dist/slice/lock.js +137 -11
  217. package/dist/story-ready/evaluate.d.ts +2 -0
  218. package/dist/story-ready/evaluate.js +13 -0
  219. package/dist/swarm/complete-cohort.d.ts +3 -0
  220. package/dist/swarm/complete-cohort.js +59 -11
  221. package/dist/swarm/finalize-cohort-cli.d.ts +7 -2
  222. package/dist/swarm/finalize-cohort-cli.js +165 -35
  223. package/dist/swarm/finalize-cohort.d.ts +1 -0
  224. package/dist/swarm/finalize-cohort.js +47 -4
  225. package/dist/swarm/launch.d.ts +22 -0
  226. package/dist/swarm/launch.js +155 -0
  227. package/dist/swarm/routing-set-cli.d.ts +11 -1
  228. package/dist/swarm/routing-set-cli.js +15 -3
  229. package/dist/swarm/routing-verify.d.ts +13 -1
  230. package/dist/swarm/routing-verify.js +60 -21
  231. package/dist/swarm/routing.d.ts +14 -0
  232. package/dist/swarm/routing.js +53 -3
  233. package/dist/telemetry-coverage/fake-trial.js +10 -0
  234. package/dist/telemetry-coverage/kinds.js +2 -0
  235. package/dist/triage/actions/index.js +4 -1
  236. package/dist/triage/bootstrap/index.js +6 -6
  237. package/dist/triage/help/registry-data.d.ts +1 -1
  238. package/dist/triage/help/registry-data.js +1 -1
  239. package/dist/triage/welcome/writers.d.ts +1 -1
  240. package/dist/triage/welcome/writers.js +10 -5
  241. package/dist/ts-check-lane/index.d.ts +3 -0
  242. package/dist/ts-check-lane/index.js +2 -0
  243. package/dist/ts-check-lane/progress-reporter.d.ts +17 -0
  244. package/dist/ts-check-lane/progress-reporter.js +38 -0
  245. package/dist/ts-check-lane/progress.d.ts +32 -0
  246. package/dist/ts-check-lane/progress.js +57 -0
  247. package/dist/ts-check-lane/run-lane.d.ts +3 -1
  248. package/dist/ts-check-lane/run-lane.js +8 -6
  249. package/dist/validate-content/validate-links.d.ts +8 -0
  250. package/dist/validate-content/validate-links.js +9 -15
  251. package/dist/value/feedback-file.js +12 -2
  252. package/dist/value/readback.d.ts +4 -1
  253. package/dist/value/readback.js +51 -12
  254. package/dist/vbrief-build/index.d.ts +1 -0
  255. package/dist/vbrief-build/index.js +1 -0
  256. package/dist/vbrief-build/project-invariants-io.d.ts +16 -0
  257. package/dist/vbrief-build/project-invariants-io.js +41 -0
  258. package/dist/vbrief-reconcile/graph.js +18 -1
  259. package/dist/vbrief-reconcile/index.d.ts +1 -1
  260. package/dist/vbrief-reconcile/index.js +1 -1
  261. package/dist/vbrief-reconcile/types.d.ts +13 -0
  262. package/dist/vbrief-reconcile/umbrellas.d.ts +14 -0
  263. package/dist/vbrief-reconcile/umbrellas.js +261 -26
  264. package/dist/vbrief-validate/index.d.ts +1 -1
  265. package/dist/vbrief-validate/index.js +1 -1
  266. package/dist/vbrief-validate/plan-hooks.d.ts +4 -0
  267. package/dist/vbrief-validate/plan-hooks.js +68 -0
  268. package/dist/vbrief-validate/schema.d.ts +4 -0
  269. package/dist/vbrief-validate/schema.js +1 -1
  270. package/dist/verify-ac/evaluate.d.ts +7 -1
  271. package/dist/verify-ac/evaluate.js +34 -26
  272. package/dist/verify-ac/flag.d.ts +4 -0
  273. package/dist/verify-ac/flag.js +16 -0
  274. package/dist/verify-ac/index.d.ts +2 -2
  275. package/dist/verify-ac/index.js +2 -2
  276. package/dist/verify-env/agent-hook-readiness.d.ts +2 -2
  277. package/dist/verify-env/agent-hook-readiness.js +12 -8
  278. package/dist/verify-env/agent-hooks-live-probe.d.ts +5 -1
  279. package/dist/verify-env/agent-hooks-live-probe.js +26 -5
  280. package/dist/verify-env/agent-hooks.js +3 -4
  281. package/dist/verify-source/contained-writes.js +2 -0
  282. package/dist/verify-source/verify-stubs.d.ts +15 -1
  283. package/dist/verify-source/verify-stubs.js +20 -16
  284. package/dist/vitest-runner/win32-coverage-tmp-setup.d.ts +5 -6
  285. package/dist/vitest-runner/win32-coverage-tmp-setup.js +5 -6
  286. package/dist/xbrief-migrate/migrate-project.js +2 -5
  287. package/package.json +7 -3
@@ -72,10 +72,9 @@ export function classifyIdentityKind(options) {
72
72
  function isCloudHeadless(environ) {
73
73
  if (envTruthy(environ, "CURSOR_AGENT"))
74
74
  return true;
75
- if (envTruthy(environ, "GROK_BUILD"))
76
- return true;
75
+ // GROK_BUILD / DEFT_AGENT_RUNTIME=grok-build identify a local TUI, not CI (#3469).
77
76
  const runtime = (environ.DEFT_AGENT_RUNTIME ?? "").trim().toLowerCase();
78
- if (runtime === "grok-build" || runtime === "cloud" || runtime === "headless")
77
+ if (runtime === "cloud" || runtime === "headless")
79
78
  return true;
80
79
  if (envTruthy(environ, "GITHUB_ACTIONS") || envTruthy(environ, "BUILDKITE"))
81
80
  return true;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Typed plan.policy.baseBranch (#3388).
3
+ *
4
+ * Integration-branch source for the shared branch-sync detector. Distinct from
5
+ * deliveryBranch (dest). Unset or invalid baseBranch resolves to dest so sync
6
+ * is a no-op. origin/develop is never identity; it may only emit a hint.
7
+ */
8
+ import { type GitRunner } from "../session/git.js";
9
+ export declare const FIELD_BASE_BRANCH = "plan.policy.baseBranch";
10
+ export declare const FIELD_BASE_BRANCH_CLI_ALIAS = "baseBranch";
11
+ /** Nudge only — never used as dest or source identity (#3388 / #3377 Q1). */
12
+ export declare const ORIGIN_DEVELOP_HINT = "origin/develop exists; set plan.policy.baseBranch if this repo uses an integration branch";
13
+ export type BaseBranchSource = "typed" | "equals-dest" | "default-on-error";
14
+ export interface BaseBranchResult {
15
+ readonly branch: string;
16
+ readonly dest: string;
17
+ readonly source: BaseBranchSource;
18
+ readonly typed: boolean;
19
+ readonly error: string | null;
20
+ readonly developHint: string | null;
21
+ }
22
+ /**
23
+ * Resolve plan.policy.baseBranch (#3388).
24
+ *
25
+ * Unset or invalid values equal dest (deliveryBranch). origin/develop is never
26
+ * substituted as the source.
27
+ */
28
+ export declare function resolveBaseBranch(projectRoot: string, runGit?: GitRunner): BaseBranchResult;
29
+ export interface BaseBranchPolicyField {
30
+ readonly name: string;
31
+ readonly current: string;
32
+ readonly default: string;
33
+ readonly source: string;
34
+ }
35
+ /** Inspector row for `task policy:show --field=baseBranch` (#3388). */
36
+ export declare function inspectBaseBranch(_data: Record<string, unknown> | null, projectRoot?: string): BaseBranchPolicyField;
37
+ //# sourceMappingURL=base-branch.d.ts.map
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Typed plan.policy.baseBranch (#3388).
3
+ *
4
+ * Integration-branch source for the shared branch-sync detector. Distinct from
5
+ * deliveryBranch (dest). Unset or invalid baseBranch resolves to dest so sync
6
+ * is a no-op. origin/develop is never identity; it may only emit a hint.
7
+ */
8
+ import { defaultGitRunner } from "../session/git.js";
9
+ import { DEFAULT_DELIVERY_BRANCH_FALLBACK, resolveDeliveryBranch } from "./delivery-branch.js";
10
+ import { readPlanPolicy } from "./plan-extensions.js";
11
+ import { loadProjectDefinition } from "./resolve.js";
12
+ export const FIELD_BASE_BRANCH = "plan.policy.baseBranch";
13
+ export const FIELD_BASE_BRANCH_CLI_ALIAS = "baseBranch";
14
+ /** Nudge only — never used as dest or source identity (#3388 / #3377 Q1). */
15
+ export const ORIGIN_DEVELOP_HINT = "origin/develop exists; set plan.policy.baseBranch if this repo uses an integration branch";
16
+ function originRefExists(projectRoot, branch, runGit) {
17
+ const check = runGit(projectRoot, [
18
+ "show-ref",
19
+ "--verify",
20
+ "--quiet",
21
+ `refs/remotes/origin/${branch}`,
22
+ ]);
23
+ return check.code === 0;
24
+ }
25
+ function developHintIfEligible(projectRoot, typed, runGit) {
26
+ if (typed)
27
+ return null;
28
+ if (!originRefExists(projectRoot, "develop", runGit))
29
+ return null;
30
+ return ORIGIN_DEVELOP_HINT;
31
+ }
32
+ /**
33
+ * Resolve plan.policy.baseBranch (#3388).
34
+ *
35
+ * Unset or invalid values equal dest (deliveryBranch). origin/develop is never
36
+ * substituted as the source.
37
+ */
38
+ export function resolveBaseBranch(projectRoot, runGit = defaultGitRunner) {
39
+ const dest = resolveDeliveryBranch(projectRoot, runGit).branch || DEFAULT_DELIVERY_BRANCH_FALLBACK;
40
+ const [data, err] = loadProjectDefinition(projectRoot);
41
+ if (data === null) {
42
+ return {
43
+ branch: dest,
44
+ dest,
45
+ source: "equals-dest",
46
+ typed: false,
47
+ error: err,
48
+ developHint: developHintIfEligible(projectRoot, false, runGit),
49
+ };
50
+ }
51
+ const plan = data.plan;
52
+ if (typeof plan !== "object" || plan === null || Array.isArray(plan)) {
53
+ return {
54
+ branch: dest,
55
+ dest,
56
+ source: "equals-dest",
57
+ typed: false,
58
+ error: "PROJECT-DEFINITION 'plan' is not an object",
59
+ developHint: developHintIfEligible(projectRoot, false, runGit),
60
+ };
61
+ }
62
+ const policyBlock = readPlanPolicy(plan);
63
+ if (typeof policyBlock === "object" &&
64
+ policyBlock !== null &&
65
+ !Array.isArray(policyBlock) &&
66
+ "baseBranch" in policyBlock) {
67
+ const raw = policyBlock.baseBranch;
68
+ if (typeof raw !== "string" || raw.trim().length === 0) {
69
+ return {
70
+ branch: dest,
71
+ dest,
72
+ source: "default-on-error",
73
+ typed: false,
74
+ error: `plan.policy.baseBranch must be a non-empty string; got ${typeof raw}`,
75
+ developHint: developHintIfEligible(projectRoot, false, runGit),
76
+ };
77
+ }
78
+ return {
79
+ branch: raw.trim(),
80
+ dest,
81
+ source: "typed",
82
+ typed: true,
83
+ error: null,
84
+ developHint: null,
85
+ };
86
+ }
87
+ return {
88
+ branch: dest,
89
+ dest,
90
+ source: "equals-dest",
91
+ typed: false,
92
+ error: null,
93
+ developHint: developHintIfEligible(projectRoot, false, runGit),
94
+ };
95
+ }
96
+ /** Inspector row for `task policy:show --field=baseBranch` (#3388). */
97
+ export function inspectBaseBranch(_data, projectRoot) {
98
+ if (projectRoot === undefined || projectRoot.length === 0) {
99
+ return {
100
+ name: FIELD_BASE_BRANCH,
101
+ current: DEFAULT_DELIVERY_BRANCH_FALLBACK,
102
+ default: DEFAULT_DELIVERY_BRANCH_FALLBACK,
103
+ source: "equals-dest",
104
+ };
105
+ }
106
+ const resolved = resolveBaseBranch(projectRoot);
107
+ return {
108
+ name: FIELD_BASE_BRANCH,
109
+ current: resolved.branch,
110
+ default: resolved.dest,
111
+ source: resolved.source,
112
+ };
113
+ }
114
+ //# sourceMappingURL=base-branch.js.map
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Shared branch-sync detector (#3388 / #3377 Wave 1).
3
+ *
4
+ * Dest = deliveryBranch. Source = typed baseBranch (unset equals dest → not a
5
+ * sync). Predicate: PR base is dest AND head is already on origin/<source>
6
+ * after fetch (tip or ancestor). Name-only and label-only exemptions are not
7
+ * implemented. origin/develop is never load-bearing identity.
8
+ *
9
+ * This module is the only is-this-a-sync source for later children (#3390/#3391)
10
+ * and for core-guard.
11
+ */
12
+ import { type GitRunner } from "../session/git.js";
13
+ /** Dest-ref blob used for dest/source. Never the PR working tree (#3388 P1). */
14
+ export declare const BRANCH_SYNC_POLICY_BLOB = "xbrief/PROJECT-DEFINITION.xbrief.json";
15
+ export declare const BRANCH_SYNC_EXEMPTION_PREFIX = "sync PR detected: all commits already guard-checked on";
16
+ export type BranchSyncReason = "source-equals-dest" | "base-is-not-dest" | "fetch-failed" | "head-not-on-integration" | "sync";
17
+ export interface BranchSyncDetection {
18
+ readonly isSync: boolean;
19
+ readonly dest: string;
20
+ readonly source: string;
21
+ readonly sourceTyped: boolean;
22
+ readonly reason: BranchSyncReason;
23
+ readonly message: string;
24
+ readonly developHint: string | null;
25
+ }
26
+ export interface DetectBranchSyncInput {
27
+ readonly dest: string;
28
+ readonly source: string;
29
+ readonly sourceTyped: boolean;
30
+ readonly prBase: string;
31
+ readonly headSha: string;
32
+ readonly projectRoot: string;
33
+ readonly developHint?: string | null;
34
+ readonly runGit?: GitRunner;
35
+ }
36
+ export declare function formatBranchSyncExemptionMessage(integrationBranch: string): string;
37
+ /**
38
+ * Evidence-based sync predicate (#3388 Q3). Fetch first. Do not trust PR
39
+ * branch names or labels.
40
+ */
41
+ export declare function detectBranchSync(input: DetectBranchSyncInput): BranchSyncDetection;
42
+ export interface DestRefSyncPolicy {
43
+ readonly dest: string;
44
+ readonly source: string;
45
+ readonly sourceTyped: boolean;
46
+ readonly developHint: string | null;
47
+ }
48
+ /**
49
+ * Load dest/source from origin/<prBase>, not the PR checkout.
50
+ *
51
+ * A feature PR that rewrites working-tree baseBranch cannot become a sync.
52
+ */
53
+ export declare function resolveSyncPolicyFromDestRef(options: {
54
+ readonly projectRoot: string;
55
+ readonly prBase: string;
56
+ readonly runGit?: GitRunner;
57
+ }): DestRefSyncPolicy;
58
+ /** Load dest/source from dest-ref policy, then run {@link detectBranchSync}. */
59
+ export declare function detectBranchSyncFromProject(options: {
60
+ readonly projectRoot: string;
61
+ readonly prBase: string;
62
+ readonly headSha: string;
63
+ readonly runGit?: GitRunner;
64
+ }): BranchSyncDetection;
65
+ export interface CoreGuardSyncExemption {
66
+ readonly wouldFail: boolean;
67
+ readonly loudMessage: string | null;
68
+ }
69
+ /**
70
+ * Core-guard mix result after the shared sync predicate. Sync PRs pass
71
+ * loudly; mixed feature PRs still fail.
72
+ */
73
+ export declare function applyCoreGuardWithBranchSync(classification: {
74
+ readonly wouldFail: boolean;
75
+ }, sync: BranchSyncDetection): CoreGuardSyncExemption;
76
+ /** Compact Python body for the deposited deft-core-guard (#3388). */
77
+ export declare function coreGuardBranchSyncPythonBody(): readonly string[];
78
+ /** Indented `if` block: detector success exits 0 (loud print); else fall through. */
79
+ export declare function renderCoreGuardBranchSyncIfBlock(indent: string): string;
80
+ //# sourceMappingURL=branch-sync.d.ts.map
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Shared branch-sync detector (#3388 / #3377 Wave 1).
3
+ *
4
+ * Dest = deliveryBranch. Source = typed baseBranch (unset equals dest → not a
5
+ * sync). Predicate: PR base is dest AND head is already on origin/<source>
6
+ * after fetch (tip or ancestor). Name-only and label-only exemptions are not
7
+ * implemented. origin/develop is never load-bearing identity.
8
+ *
9
+ * This module is the only is-this-a-sync source for later children (#3390/#3391)
10
+ * and for core-guard.
11
+ */
12
+ import { defaultGitRunner, gitIsAncestor } from "../session/git.js";
13
+ import { ORIGIN_DEVELOP_HINT } from "./base-branch.js";
14
+ import { resolveGitDefaultDeliveryBranch } from "./delivery-branch.js";
15
+ import { readPlanPolicy } from "./plan-extensions.js";
16
+ /** Dest-ref blob used for dest/source. Never the PR working tree (#3388 P1). */
17
+ export const BRANCH_SYNC_POLICY_BLOB = "xbrief/PROJECT-DEFINITION.xbrief.json";
18
+ export const BRANCH_SYNC_EXEMPTION_PREFIX = "sync PR detected: all commits already guard-checked on";
19
+ export function formatBranchSyncExemptionMessage(integrationBranch) {
20
+ return `${BRANCH_SYNC_EXEMPTION_PREFIX} ${integrationBranch}`;
21
+ }
22
+ function notSync(input, reason) {
23
+ return {
24
+ isSync: false,
25
+ dest: input.dest,
26
+ source: input.source,
27
+ sourceTyped: input.sourceTyped,
28
+ reason,
29
+ message: "",
30
+ developHint: input.developHint ?? null,
31
+ };
32
+ }
33
+ /**
34
+ * Evidence-based sync predicate (#3388 Q3). Fetch first. Do not trust PR
35
+ * branch names or labels.
36
+ */
37
+ export function detectBranchSync(input) {
38
+ const dest = input.dest.trim();
39
+ const source = input.source.trim();
40
+ if (source.length === 0 || dest.length === 0 || source === dest) {
41
+ return notSync({ ...input, dest, source }, "source-equals-dest");
42
+ }
43
+ if (input.prBase.trim() !== dest) {
44
+ return notSync({ ...input, dest, source }, "base-is-not-dest");
45
+ }
46
+ const runGit = input.runGit ?? defaultGitRunner;
47
+ const fetched = runGit(input.projectRoot, ["fetch", "--quiet", "origin", source]);
48
+ if (fetched.code !== 0) {
49
+ return notSync({ ...input, dest, source }, "fetch-failed");
50
+ }
51
+ const onIntegration = gitIsAncestor(input.projectRoot, input.headSha, `origin/${source}`, runGit);
52
+ if (onIntegration !== true) {
53
+ return notSync({ ...input, dest, source }, "head-not-on-integration");
54
+ }
55
+ return {
56
+ isSync: true,
57
+ dest,
58
+ source,
59
+ sourceTyped: input.sourceTyped,
60
+ reason: "sync",
61
+ message: formatBranchSyncExemptionMessage(source),
62
+ developHint: input.developHint ?? null,
63
+ };
64
+ }
65
+ function parseTypedPolicyBranches(jsonText) {
66
+ try {
67
+ const data = JSON.parse(jsonText);
68
+ if (typeof data !== "object" || data === null || Array.isArray(data)) {
69
+ return { dest: null, source: null };
70
+ }
71
+ const policyBlock = readPlanPolicy(data.plan);
72
+ if (typeof policyBlock !== "object" || policyBlock === null || Array.isArray(policyBlock)) {
73
+ return { dest: null, source: null };
74
+ }
75
+ const rec = policyBlock;
76
+ const destRaw = rec.deliveryBranch;
77
+ const sourceRaw = rec.baseBranch;
78
+ return {
79
+ dest: typeof destRaw === "string" && destRaw.trim().length > 0 ? destRaw.trim() : null,
80
+ source: typeof sourceRaw === "string" && sourceRaw.trim().length > 0 ? sourceRaw.trim() : null,
81
+ };
82
+ }
83
+ catch {
84
+ return { dest: null, source: null };
85
+ }
86
+ }
87
+ /**
88
+ * Load dest/source from origin/<prBase>, not the PR checkout.
89
+ *
90
+ * A feature PR that rewrites working-tree baseBranch cannot become a sync.
91
+ */
92
+ export function resolveSyncPolicyFromDestRef(options) {
93
+ const runGit = options.runGit ?? defaultGitRunner;
94
+ const prBase = options.prBase.trim();
95
+ const fetched = runGit(options.projectRoot, ["fetch", "--quiet", "origin", prBase]);
96
+ if (fetched.code !== 0) {
97
+ const dest = resolveGitDefaultDeliveryBranch(options.projectRoot, runGit);
98
+ const developHint = runGit(options.projectRoot, [
99
+ "show-ref",
100
+ "--verify",
101
+ "--quiet",
102
+ "refs/remotes/origin/develop",
103
+ ]).code === 0
104
+ ? ORIGIN_DEVELOP_HINT
105
+ : null;
106
+ return { dest, source: dest, sourceTyped: false, developHint };
107
+ }
108
+ const shown = runGit(options.projectRoot, [
109
+ "show",
110
+ `origin/${prBase}:${BRANCH_SYNC_POLICY_BLOB}`,
111
+ ]);
112
+ const parsed = shown.code === 0 && shown.stdout.length > 0
113
+ ? parseTypedPolicyBranches(shown.stdout)
114
+ : { dest: null, source: null };
115
+ const dest = parsed.dest ?? resolveGitDefaultDeliveryBranch(options.projectRoot, runGit);
116
+ const sourceTyped = parsed.source !== null;
117
+ const source = parsed.source ?? dest;
118
+ const developHint = sourceTyped ||
119
+ runGit(options.projectRoot, ["show-ref", "--verify", "--quiet", "refs/remotes/origin/develop"])
120
+ .code !== 0
121
+ ? null
122
+ : ORIGIN_DEVELOP_HINT;
123
+ return { dest, source, sourceTyped, developHint };
124
+ }
125
+ /** Load dest/source from dest-ref policy, then run {@link detectBranchSync}. */
126
+ export function detectBranchSyncFromProject(options) {
127
+ const runGit = options.runGit ?? defaultGitRunner;
128
+ const policy = resolveSyncPolicyFromDestRef({
129
+ projectRoot: options.projectRoot,
130
+ prBase: options.prBase,
131
+ runGit,
132
+ });
133
+ return detectBranchSync({
134
+ dest: policy.dest,
135
+ source: policy.source,
136
+ sourceTyped: policy.sourceTyped,
137
+ prBase: options.prBase,
138
+ headSha: options.headSha,
139
+ projectRoot: options.projectRoot,
140
+ developHint: policy.developHint,
141
+ runGit,
142
+ });
143
+ }
144
+ /**
145
+ * Core-guard mix result after the shared sync predicate. Sync PRs pass
146
+ * loudly; mixed feature PRs still fail.
147
+ */
148
+ export function applyCoreGuardWithBranchSync(classification, sync) {
149
+ if (!classification.wouldFail) {
150
+ return { wouldFail: false, loudMessage: null };
151
+ }
152
+ if (sync.isSync) {
153
+ return { wouldFail: false, loudMessage: formatBranchSyncExemptionMessage(sync.source) };
154
+ }
155
+ return { wouldFail: true, loudMessage: null };
156
+ }
157
+ /** Compact Python body for the deposited deft-core-guard (#3388). */
158
+ export function coreGuardBranchSyncPythonBody() {
159
+ return [
160
+ "import json, subprocess, sys",
161
+ "head_sha, pr_base = sys.argv[1], sys.argv[2]",
162
+ "def git(*a):",
163
+ " return subprocess.run(['git', *a], capture_output=True, text=True)",
164
+ "dest = source = None",
165
+ "if git('fetch', '--quiet', 'origin', pr_base).returncode != 0: sys.exit(1)",
166
+ `shown = git('show', 'origin/' + pr_base + ':${BRANCH_SYNC_POLICY_BLOB}')`,
167
+ "if shown.returncode == 0:",
168
+ " try:",
169
+ " plan = json.loads(shown.stdout).get('plan')",
170
+ " except Exception:",
171
+ " plan = None",
172
+ " if isinstance(plan, dict):",
173
+ " pol = plan.get('x-directive/policy') or plan.get('policy') or {}",
174
+ " if isinstance(pol, dict):",
175
+ " d, s = pol.get('deliveryBranch'), pol.get('baseBranch')",
176
+ " if isinstance(d, str) and d.strip(): dest = d.strip()",
177
+ " if isinstance(s, str) and s.strip(): source = s.strip()",
178
+ "if not dest:",
179
+ " r = git('symbolic-ref', 'refs/remotes/origin/HEAD', '--short')",
180
+ " if r.returncode == 0 and r.stdout.strip():",
181
+ " dest = r.stdout.strip().split('/', 1)[-1]",
182
+ " else:",
183
+ " for n in ('main', 'master'):",
184
+ " if git('show-ref', '--verify', '--quiet', 'refs/remotes/origin/' + n).returncode == 0:",
185
+ " dest = n",
186
+ " break",
187
+ " if not dest:",
188
+ " for n in ('main', 'master'):",
189
+ " if git('show-ref', '--verify', '--quiet', 'refs/heads/' + n).returncode == 0:",
190
+ " dest = n",
191
+ " break",
192
+ " if not dest: dest = 'master'",
193
+ "if not source: source = dest",
194
+ "if source == dest or pr_base != dest: sys.exit(1)",
195
+ "if git('fetch', '--quiet', 'origin', source).returncode != 0: sys.exit(1)",
196
+ "if git('merge-base', '--is-ancestor', head_sha, 'origin/' + source).returncode != 0: sys.exit(1)",
197
+ `print('${BRANCH_SYNC_EXEMPTION_PREFIX} ' + source)`,
198
+ ];
199
+ }
200
+ /** Indented `if` block: detector success exits 0 (loud print); else fall through. */
201
+ export function renderCoreGuardBranchSyncIfBlock(indent) {
202
+ return [
203
+ `${indent}if python3 - "$HEAD_SHA" "$BASE_REF" <<'PY'`,
204
+ ...coreGuardBranchSyncPythonBody().map((line) => `${indent}${line}`),
205
+ `${indent}PY`,
206
+ `${indent}then`,
207
+ `${indent} exit 0`,
208
+ `${indent}fi`,
209
+ ].join("\n");
210
+ }
211
+ //# sourceMappingURL=branch-sync.js.map
@@ -77,6 +77,7 @@ export function emitCeremonyDialEscalationEvaluation(options) {
77
77
  projectRoot: options.projectRoot,
78
78
  sessionId: options.sessionId,
79
79
  env: options.env,
80
+ component: "ceremony-dial",
80
81
  });
81
82
  emitter.emitDialEscalationEvaluation({
82
83
  tier: options.evaluation.tier,
@@ -23,7 +23,7 @@ import { RunSummaryEmitter } from "../run-summary/emit.js";
23
23
  import { atomicWriteProjectDefinition, projectDefinitionMutationLock, } from "../vbrief-build/project-definition-io.js";
24
24
  import { migrateLegacyPolicyKey, PLAN_POLICY_KEY, readPlanPolicy } from "./plan-extensions.js";
25
25
  import { policyColonInvocation } from "./policy-invocation.js";
26
- import { appendAuditLog, loadProjectDefinition, projectDefinitionPath } from "./resolve.js";
26
+ import { appendAuditLog, loadProjectDefinition, POLICY_AUDIT_NOOP_STDOUT, projectDefinitionPath, } from "./resolve.js";
27
27
  /** Canonical dotted policy field name. */
28
28
  export const FIELD_CEREMONY_DIAL = "plan.policy.ceremonyDial";
29
29
  /** Short alias for `policy:show --field=ceremonyDial`. */
@@ -527,7 +527,7 @@ export function setCeremonyDial(projectRoot, options) {
527
527
  }
528
528
  }
529
529
  const plan = data.plan;
530
- migrateLegacyPolicyKey(plan);
530
+ const legacyKeyMigrated = migrateLegacyPolicyKey(plan);
531
531
  const existingPolicy = plan[PLAN_POLICY_KEY];
532
532
  if (typeof existingPolicy !== "object" ||
533
533
  existingPolicy === null ||
@@ -564,7 +564,9 @@ export function setCeremonyDial(projectRoot, options) {
564
564
  override: nextOverride,
565
565
  };
566
566
  const prevParsed = parseConfig(previous).config;
567
- const changedFlag = prevParsed.enabled !== nextBlock.enabled || prevParsed.override !== nextBlock.override;
567
+ const changedFlag = prevParsed.enabled !== nextBlock.enabled ||
568
+ prevParsed.override !== nextBlock.override ||
569
+ legacyKeyMigrated;
568
570
  policyBlock.ceremonyDial = nextBlock;
569
571
  if (changedFlag) {
570
572
  atomicWriteProjectDefinition(path, data);
@@ -580,15 +582,13 @@ export function setCeremonyDial(projectRoot, options) {
580
582
  if (note) {
581
583
  parts.push(`note=${note.replace(/\n/g, " ").replace(/\r/g, " ")}`);
582
584
  }
583
- appendAuditLog(projectRoot, parts.join(" "));
585
+ appendAuditLog(projectRoot, parts.join(" "), changedFlag);
584
586
  return { changed: changedFlag };
585
587
  });
586
588
  const resolved = resolveCeremonyDial(projectRoot);
587
589
  const lines = [
588
590
  `\u2713 ${FIELD_CEREMONY_DIAL} updated.`,
589
- changed
590
- ? " audit: meta/policy-changes.log updated."
591
- : " no-op: value already matched (audit entry still appended for trail).",
591
+ changed ? " audit: meta/policy-changes.log updated." : POLICY_AUDIT_NOOP_STDOUT,
592
592
  formatCeremonyDialStatusLine(resolved),
593
593
  ];
594
594
  return { exitCode: 0, stdout: `${lines.join("\n")}\n`, changed };
@@ -990,12 +990,6 @@ export function escalateCeremonyDial(projectRoot, options) {
990
990
  return;
991
991
  }
992
992
  try {
993
- const audit = readCeremonyDialAudit(projectRoot);
994
- const rawSid = audit.raw?.session_id;
995
- const sid = options.sessionId ??
996
- (typeof rawSid === "string" && rawSid.length > 0
997
- ? rawSid
998
- : `dial-${Date.now().toString(36)}`);
999
993
  const rank = {
1000
994
  minimal: 0,
1001
995
  rapid: 1,
@@ -1012,8 +1006,9 @@ export function escalateCeremonyDial(projectRoot, options) {
1012
1006
  : baseReason;
1013
1007
  const emitter = new RunSummaryEmitter({
1014
1008
  projectRoot,
1015
- sessionId: sid,
1009
+ sessionId: options.sessionId,
1016
1010
  env: options.env,
1011
+ component: "ceremony-dial",
1017
1012
  });
1018
1013
  emitter.emitDialEscalationEvaluation({
1019
1014
  tier: outcome === "escalated" ? options.to : from,
@@ -1065,16 +1060,11 @@ export function escalateCeremonyDial(projectRoot, options) {
1065
1060
  // #3282: event-driven dial_transition line (fail-open).
1066
1061
  if (options.emitRunSummary !== false) {
1067
1062
  try {
1068
- const audit = readCeremonyDialAudit(projectRoot);
1069
- const rawSid = audit.raw?.session_id;
1070
- const sid = options.sessionId ??
1071
- (typeof rawSid === "string" && rawSid.length > 0
1072
- ? rawSid
1073
- : `dial-${Date.now().toString(36)}`);
1074
1063
  const emitter = new RunSummaryEmitter({
1075
1064
  projectRoot,
1076
- sessionId: sid,
1065
+ sessionId: options.sessionId,
1077
1066
  env: options.env,
1067
+ component: "ceremony-dial",
1078
1068
  });
1079
1069
  emitter.emitDialTransition({
1080
1070
  from,
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Typed plan.policy.deliveryBranch (#3041).
3
3
  *
4
- * Distinct from swarm/PR `baseBranch` (integration target for PRs / finalize
5
- * sweep PRs). deliveryBranch is where shipped work must land for a delivered
6
- * completion disposition.
4
+ * Distinct from typed `plan.policy.baseBranch` (#3388), the integration-branch
5
+ * source for the shared branch-sync detector. deliveryBranch is dest: where
6
+ * shipped work must land for a delivered completion disposition.
7
7
  */
8
8
  import { type GitRunner } from "../session/git.js";
9
9
  export declare const FIELD_DELIVERY_BRANCH = "plan.policy.deliveryBranch";
@@ -16,6 +16,8 @@ export interface DeliveryBranchResult {
16
16
  readonly source: DeliveryBranchSource;
17
17
  readonly error: string | null;
18
18
  }
19
+ /** Git-only dest when dest-ref policy has no typed deliveryBranch (#3388). */
20
+ export declare function resolveGitDefaultDeliveryBranch(projectRoot: string, runGit?: GitRunner): string;
19
21
  /**
20
22
  * Resolve the project's delivery branch (#3041).
21
23
  *
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Typed plan.policy.deliveryBranch (#3041).
3
3
  *
4
- * Distinct from swarm/PR `baseBranch` (integration target for PRs / finalize
5
- * sweep PRs). deliveryBranch is where shipped work must land for a delivered
6
- * completion disposition.
4
+ * Distinct from typed `plan.policy.baseBranch` (#3388), the integration-branch
5
+ * source for the shared branch-sync detector. deliveryBranch is dest: where
6
+ * shipped work must land for a delivered completion disposition.
7
7
  */
8
8
  import { defaultGitRunner } from "../session/git.js";
9
9
  import { readPlanPolicy } from "./plan-extensions.js";
@@ -50,6 +50,10 @@ function defaultBranchCandidates(projectRoot, runGit) {
50
50
  }
51
51
  return candidates;
52
52
  }
53
+ /** Git-only dest when dest-ref policy has no typed deliveryBranch (#3388). */
54
+ export function resolveGitDefaultDeliveryBranch(projectRoot, runGit = defaultGitRunner) {
55
+ return defaultBranchCandidates(projectRoot, runGit)[0] ?? DEFAULT_DELIVERY_BRANCH_FALLBACK;
56
+ }
53
57
  /**
54
58
  * Resolve the project's delivery branch (#3041).
55
59
  *
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Single machine-readable source of truth for per-file size guidance (#3424).
3
+ *
4
+ * `coding.md` and companion prose MUST reference these exports. They are
5
+ * review / planning triggers, not a hard line cap (#1488).
6
+ */
7
+ /** Preferred size for a focused file. */
8
+ export declare const FILE_SIZE_IDEAL_LINES = 300;
9
+ /** Recommended upper bound before a file should be treated as large. */
10
+ export declare const FILE_SIZE_RECOMMENDED_LINES = 500;
11
+ /**
12
+ * Review-trigger line count. A declared file at or above this size cannot
13
+ * pass preflight without a recorded split plan or cohesion exemption.
14
+ * Size alone is never a fail-closed reject.
15
+ */
16
+ export declare const FILE_SIZE_REVIEW_TRIGGER_LINES = 1000;
17
+ /** Canonical bundle so callers do not restate the three numbers. */
18
+ export declare const FILE_SIZE_THRESHOLDS: {
19
+ readonly idealLines: 300;
20
+ readonly recommendedLines: 500;
21
+ readonly reviewTriggerLines: 1000;
22
+ };
23
+ export type FileSizeThresholds = typeof FILE_SIZE_THRESHOLDS;
24
+ //# sourceMappingURL=file-size-thresholds.d.ts.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Single machine-readable source of truth for per-file size guidance (#3424).
3
+ *
4
+ * `coding.md` and companion prose MUST reference these exports. They are
5
+ * review / planning triggers, not a hard line cap (#1488).
6
+ */
7
+ /** Preferred size for a focused file. */
8
+ export const FILE_SIZE_IDEAL_LINES = 300;
9
+ /** Recommended upper bound before a file should be treated as large. */
10
+ export const FILE_SIZE_RECOMMENDED_LINES = 500;
11
+ /**
12
+ * Review-trigger line count. A declared file at or above this size cannot
13
+ * pass preflight without a recorded split plan or cohesion exemption.
14
+ * Size alone is never a fail-closed reject.
15
+ */
16
+ export const FILE_SIZE_REVIEW_TRIGGER_LINES = 1000;
17
+ /** Canonical bundle so callers do not restate the three numbers. */
18
+ export const FILE_SIZE_THRESHOLDS = {
19
+ idealLines: FILE_SIZE_IDEAL_LINES,
20
+ recommendedLines: FILE_SIZE_RECOMMENDED_LINES,
21
+ reviewTriggerLines: FILE_SIZE_REVIEW_TRIGGER_LINES,
22
+ };
23
+ //# sourceMappingURL=file-size-thresholds.js.map