@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
@@ -198,13 +198,16 @@ export function resolveDeliveryTip(projectRoot, tipOverride, runGit) {
198
198
  return { tip: candidate, error: null };
199
199
  }
200
200
  }
201
- // Last resort: HEAD of current checkout (still a real tip for fixtures).
202
- if (refExists(projectRoot, "HEAD", runGit)) {
203
- return { tip: "HEAD", error: null };
204
- }
201
+ // HEAD fallback (#3478 review). This gate exists to prove an artifact landed
202
+ // on the delivery tip rather than on feature-worktree HEAD; falling back to
203
+ // HEAD when the delivery ref is missing (shallow clone, unfetched worktree,
204
+ // fetch-depth:1 checkout) checks the very branch whose land is in question and
205
+ // silently passes. Unresolvable delivery tip must fail closed -- pass an
206
+ // explicit --tip (e.g. --tip HEAD for an in-flight land PR) to opt in.
205
207
  return {
206
208
  tip: null,
207
- error: `could not resolve delivery tip for branch '${branch}' (no origin/${branch}, ${branch}, or HEAD)`,
209
+ error: `could not resolve delivery tip for branch '${branch}' (no origin/${branch} or ${branch}); ` +
210
+ "fetch the delivery branch or pass an explicit --tip",
208
211
  };
209
212
  }
210
213
  function listTreePaths(projectRoot, tip, prefixes, runGit) {
@@ -270,6 +273,28 @@ function issuesFromBlobPaths(projectRoot, tip, paths, defaultRepo, runGit, origi
270
273
  }
271
274
  return hits;
272
275
  }
276
+ /**
277
+ * Narrow the origin map to the requested issue.
278
+ *
279
+ * Matching is repo-scoped when the caller's repo is known (#3478 review): a
280
+ * corpus entry for another repository's same-numbered issue must NOT survive
281
+ * this filter. Letting it through leaves `originMap` non-empty, which suppresses
282
+ * the synthesis below and makes the gate resolve the wrong `repo#number` --
283
+ * a foreign open issue then green-skips an unlanded local one.
284
+ */
285
+ function filterOriginsByIssue(originMap, issue, repo) {
286
+ const out = new Map();
287
+ for (const [key, entry] of originMap) {
288
+ if (entry.issue.number !== issue) {
289
+ continue;
290
+ }
291
+ if (repo !== null && entry.issue.repo !== repo) {
292
+ continue;
293
+ }
294
+ out.set(key, entry);
295
+ }
296
+ return out;
297
+ }
273
298
  function mergeOrigins(hits) {
274
299
  const map = new Map();
275
300
  for (const hit of hits) {
@@ -353,7 +378,47 @@ export function evaluateCompletedTracked(projectRoot, options = {}) {
353
378
  const localHits = scanLocalOrigins(root, defaultRepo);
354
379
  const tipNonterminalPaths = listTreePaths(root, tip, nonterminalPrefixes(), runGit);
355
380
  const tipNonterminalHits = issuesFromBlobPaths(root, tip, tipNonterminalPaths, defaultRepo, runGit, `tip:${tip}`);
356
- const originMap = mergeOrigins([...localHits, ...tipNonterminalHits]);
381
+ let originMap = mergeOrigins([...localHits, ...tipNonterminalHits]);
382
+ // Delivery tip only — the land invariant is post-merge tip truth (#3264 AC).
383
+ // Lifecycle PRs that commit completed/ on a feature branch are not expected
384
+ // to satisfy this gate until merge; run the verb with --tip HEAD when
385
+ // validating an in-flight land PR. The gate is a standalone verify verb
386
+ // (not wired into check:consumer) so product PRs are not deadlocked.
387
+ const tipTerminalPaths = listTreePaths(root, tip, terminalPrefixes(), runGit);
388
+ const tipTerminalHits = issuesFromBlobPaths(root, tip, tipTerminalPaths, defaultRepo, runGit, `tip:${tip}`);
389
+ const landedKeys = new Set(tipTerminalHits.map((h) => issueKey(h.issue)));
390
+ const issueFilter = options.issue ?? null;
391
+ if (issueFilter !== null) {
392
+ if (!Number.isInteger(issueFilter) || issueFilter <= 0) {
393
+ return {
394
+ code: 2,
395
+ message: `verify:completed-tracked: --issue must be a positive integer (got ${issueFilter})`,
396
+ stream: "stderr",
397
+ missing: [],
398
+ tip,
399
+ };
400
+ }
401
+ originMap = filterOriginsByIssue(originMap, issueFilter, defaultRepo);
402
+ // Drive-to DONE must not green-skip a named origin with no local brief
403
+ // (#3476). Synthesize the requested issue so closed+unlanded fails.
404
+ if (originMap.size === 0) {
405
+ if (defaultRepo === null) {
406
+ return {
407
+ code: 2,
408
+ message: `verify:completed-tracked: --issue ${issueFilter} requires --repo or a resolvable ` +
409
+ "origin remote when no scoped xBRIEF origin is present.",
410
+ stream: "stderr",
411
+ missing: [],
412
+ tip,
413
+ };
414
+ }
415
+ const synthetic = {
416
+ issue: { repo: defaultRepo, number: issueFilter },
417
+ origins: [`--issue ${issueFilter}`],
418
+ };
419
+ originMap.set(issueKey(synthetic.issue), synthetic);
420
+ }
421
+ }
357
422
  if (originMap.size === 0) {
358
423
  if (quiet) {
359
424
  return { code: 0, message: "", stream: "none", missing: [], tip };
@@ -366,14 +431,6 @@ export function evaluateCompletedTracked(projectRoot, options = {}) {
366
431
  tip,
367
432
  };
368
433
  }
369
- // Delivery tip only — the land invariant is post-merge tip truth (#3264 AC).
370
- // Lifecycle PRs that commit completed/ on a feature branch are not expected
371
- // to satisfy this gate until merge; run the verb with --tip HEAD when
372
- // validating an in-flight land PR. The gate is a standalone verify verb
373
- // (not wired into check:consumer) so product PRs are not deadlocked.
374
- const tipTerminalPaths = listTreePaths(root, tip, terminalPrefixes(), runGit);
375
- const tipTerminalHits = issuesFromBlobPaths(root, tip, tipTerminalPaths, defaultRepo, runGit, `tip:${tip}`);
376
- const landedKeys = new Set(tipTerminalHits.map((h) => issueKey(h.issue)));
377
434
  const missing = [];
378
435
  for (const [key, entry] of originMap) {
379
436
  if (landedKeys.has(key)) {
@@ -383,10 +440,20 @@ export function evaluateCompletedTracked(projectRoot, options = {}) {
383
440
  if (state === "open") {
384
441
  continue;
385
442
  }
386
- // Closed: always fail. Unknown with live expected (!skipGh): also fail —
387
- // cannot prove the issue is still open, so do not green-skip land debt
388
- // (#3264 Greptile residual on live lookup failure).
389
- if (state === "closed" || (state === null && !skipGh)) {
443
+ // Closed: always fail.
444
+ //
445
+ // Unknown: fail when live lookup was expected (!skipGh) -- cannot prove the
446
+ // issue is still open, so do not green-skip land debt (#3264 Greptile
447
+ // residual on live lookup failure).
448
+ //
449
+ // Unknown also fails for an explicitly named --issue even under --skip-gh
450
+ // (#3478 review): that is the drive-to DONE form, where the caller asserts
451
+ // this specific issue is done. An uncached issue must not exit 0 there --
452
+ // otherwise --skip-gh silently turns the DONE gate into a no-op. The
453
+ // unscoped corpus scan keeps the offline allowance, since a cold cache
454
+ // legitimately knows nothing about most scoped issues.
455
+ const unknownIsTerminal = !skipGh || issueFilter !== null;
456
+ if (state === "closed" || (state === null && unknownIsTerminal)) {
390
457
  missing.push(entry);
391
458
  }
392
459
  }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * verify:lifecycle-visible — detect ignore/index flags that hide lifecycle roots (#3505).
3
+ *
4
+ * Warn-only by default (exit 0). Pass --enforce to fail closed.
5
+ * Not a task-check gate: this is a per-clone environment property.
6
+ */
7
+ import { type GitRunner } from "../session/git.js";
8
+ export declare const LIFECYCLE_ROOT_PREFIXES: readonly ["xbrief", "vbrief"];
9
+ export declare const LIFECYCLE_STAGE_DIRS: readonly ["proposed", "pending", "active", "completed", "cancelled"];
10
+ export type LifecycleHideKind = "ignored" | "skip-worktree" | "assume-unchanged";
11
+ export interface LifecycleHideFinding {
12
+ readonly path: string;
13
+ readonly kind: LifecycleHideKind;
14
+ readonly source: string;
15
+ readonly line: number | null;
16
+ readonly rule: string;
17
+ readonly raw: string;
18
+ }
19
+ export interface LifecycleVisibleOptions {
20
+ readonly projectRoot: string;
21
+ readonly enforce?: boolean;
22
+ readonly runGit?: GitRunner;
23
+ }
24
+ export interface LifecycleVisibleResult {
25
+ readonly code: 0 | 1 | 2;
26
+ readonly message: string;
27
+ readonly stream: "stdout" | "stderr";
28
+ readonly findings: readonly LifecycleHideFinding[];
29
+ readonly enforce: boolean;
30
+ readonly failOpen: boolean;
31
+ }
32
+ export interface CheckIgnoreMatch {
33
+ readonly source: string;
34
+ readonly line: number;
35
+ readonly pattern: string;
36
+ readonly path: string;
37
+ }
38
+ export interface LsFilesVerboseRecord {
39
+ readonly tag: string;
40
+ readonly path: string;
41
+ }
42
+ /** Ignore globs from one file, with the directory Git applies them against. */
43
+ export interface IgnorePatternSource {
44
+ readonly baseDir: string;
45
+ readonly patterns: readonly string[];
46
+ }
47
+ /** Canonical lifecycle root pathspecs (`xbrief/active/`, `vbrief/pending/`, …). */
48
+ export declare function lifecycleRootRelPaths(): string[];
49
+ /** Fills `*` in ignore globs so a derived probe still matches the rule. */
50
+ export declare const LIFECYCLE_PROBE_STEM = "lifecycle-visible";
51
+ /**
52
+ * Date-prefixed brief-shaped fallback when no ignore-rule date glob exists.
53
+ * Date globs emit their own matching names (`2026-07-*` → a July file, `2025-*` → 2025).
54
+ */
55
+ export declare const LIFECYCLE_PROBE_SENTINEL = "2026-01-01-lifecycle-visible.xbrief.json";
56
+ /** Legacy vbrief filename so `*.vbrief.json` / `2026-*.vbrief.json` cannot report clean. */
57
+ export declare const LIFECYCLE_PROBE_SENTINEL_VBRIEF = "2026-01-01-lifecycle-visible.vbrief.json";
58
+ /** Stage dirs plus one matching-extension sentinel under each. */
59
+ export declare function lifecycleIgnoreProbeRelPaths(): string[];
60
+ /** True when an ignore glob could hide a convention-valid brief. */
61
+ export declare function ignorePatternLooksLifecycleRelevant(pattern: string): boolean;
62
+ /** Linear `[abc]` expansion — avoid nested regex quantifiers (CodeQL js/polynomial-redos). */
63
+ export declare function expandGitignoreCharClasses(body: string): string;
64
+ /**
65
+ * Expand one gitignore glob into a single concrete pathname that still matches it.
66
+ * `*` becomes {@link LIFECYCLE_PROBE_STEM}; `**` collapses; `?` becomes `0`.
67
+ */
68
+ export declare function expandGitignoreGlobToConcrete(pattern: string): string | null;
69
+ /** Join a glob-expanded probe to the ignore file's directory (Git's match root). */
70
+ export declare function joinIgnoreFileBase(baseDir: string, concrete: string): string;
71
+ /**
72
+ * One derived probe per relevant ignore-rule line (bounded by ignore-file size, not a numeric cap).
73
+ * Date globs keep their year/month so `2026-07-*` probes a July name, not the January fallback.
74
+ * Slash patterns keep the ignore-file directory; stage wildcards expand onto real stages.
75
+ */
76
+ export declare function derivedLifecycleIgnoreProbesFromSources(sources: readonly IgnorePatternSource[]): string[];
77
+ /** Ignore-file globs → check-ignore pathspecs (one per relevant rule line). */
78
+ export declare function derivedLifecycleIgnoreProbes(projectRoot: string, runGit: GitRunner): string[];
79
+ /** Map a check-ignore pathname back to its canonical stage root, or null if outside. */
80
+ export declare function lifecycleRootForRelPath(relPosix: string): string | null;
81
+ /** Deliberate hybrid ignores under a visible root must not trip the check (#1144). */
82
+ export declare function isSelectiveLifecyclePath(relPosix: string): boolean;
83
+ /** Map git check-ignore source paths to the actionable display form. */
84
+ export declare function displayIgnoreSource(source: string, projectRoot: string): string;
85
+ /**
86
+ * Parse one `git check-ignore -v` line: `<source>:<linenum>:<pattern>\\t<pathname>`.
87
+ * Source may be a Windows absolute path with a drive colon.
88
+ */
89
+ export declare function parseCheckIgnoreVerboseLine(line: string): CheckIgnoreMatch | null;
90
+ /** Parse one `git ls-files -v` record (`S path` / `h path`). */
91
+ export declare function parseLsFilesVerboseRecord(record: string): LsFilesVerboseRecord | null;
92
+ /** Index flag encoded by the `ls-files -v` status tag. */
93
+ export declare function indexFlagKind(tag: string): "skip-worktree" | "assume-unchanged" | null;
94
+ /** Session:start advisory lines — silent when clean. */
95
+ export declare function formatLifecycleVisibleSessionLines(result: LifecycleVisibleResult): string[];
96
+ /** Evaluate whether lifecycle roots are hidden by ignore rules or index flags (#3505). */
97
+ export declare function evaluateLifecycleVisible(options: LifecycleVisibleOptions): LifecycleVisibleResult;
98
+ //# sourceMappingURL=evaluate.d.ts.map