@deftai/directive-core 0.99.0 → 0.101.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 (166) hide show
  1. package/dist/authz/actions.d.ts +6 -0
  2. package/dist/authz/actions.js +3 -0
  3. package/dist/authz/classify.js +241 -30
  4. package/dist/authz/decompose-apply.d.ts +81 -0
  5. package/dist/authz/decompose-apply.js +377 -0
  6. package/dist/authz/index.d.ts +3 -1
  7. package/dist/authz/index.js +3 -1
  8. package/dist/authz/store.d.ts +53 -0
  9. package/dist/authz/store.js +219 -1
  10. package/dist/authz/types.d.ts +19 -2
  11. package/dist/authz/types.js +5 -1
  12. package/dist/check/cached-orchestrator.d.ts +26 -5
  13. package/dist/check/cached-orchestrator.js +228 -6
  14. package/dist/check/gate-lists.d.ts +10 -4
  15. package/dist/check/gate-lists.js +19 -5
  16. package/dist/check/index.d.ts +3 -2
  17. package/dist/check/index.js +2 -1
  18. package/dist/check/named-cause.d.ts +45 -0
  19. package/dist/check/named-cause.js +121 -0
  20. package/dist/check/orchestrator.js +6 -1
  21. package/dist/doctor/checks.d.ts +44 -0
  22. package/dist/doctor/checks.js +428 -2
  23. package/dist/doctor/help.d.ts +5 -0
  24. package/dist/doctor/help.js +31 -0
  25. package/dist/doctor/index.d.ts +2 -0
  26. package/dist/doctor/index.js +2 -0
  27. package/dist/doctor/main.d.ts +6 -7
  28. package/dist/doctor/main.js +130 -79
  29. package/dist/doctor/session-coda.d.ts +82 -0
  30. package/dist/doctor/session-coda.js +151 -0
  31. package/dist/doctor/types.d.ts +16 -0
  32. package/dist/doctor/which.d.ts +20 -1
  33. package/dist/doctor/which.js +67 -1
  34. package/dist/finish-loop/pr-finish-loop.d.ts +13 -2
  35. package/dist/finish-loop/pr-finish-loop.js +116 -5
  36. package/dist/finish-loop/types.d.ts +1 -1
  37. package/dist/hooks/dispatcher.d.ts +9 -5
  38. package/dist/hooks/dispatcher.js +23 -15
  39. package/dist/hooks/readonly.d.ts +6 -3
  40. package/dist/hooks/readonly.js +44 -25
  41. package/dist/index.d.ts +3 -0
  42. package/dist/index.js +3 -0
  43. package/dist/init-deposit/agent-hooks.d.ts +20 -0
  44. package/dist/init-deposit/agent-hooks.js +51 -31
  45. package/dist/init-deposit/gitignore.js +2 -0
  46. package/dist/intake/issue-ingest.js +36 -0
  47. package/dist/lifecycle/completed-consistency.d.ts +60 -0
  48. package/dist/lifecycle/completed-consistency.js +443 -0
  49. package/dist/lifecycle/completed-tracked-on-delivery.d.ts +47 -0
  50. package/dist/lifecycle/completed-tracked-on-delivery.js +415 -0
  51. package/dist/lifecycle/index.d.ts +2 -0
  52. package/dist/lifecycle/index.js +2 -0
  53. package/dist/literal-acceptance/capture.d.ts +52 -0
  54. package/dist/literal-acceptance/capture.js +658 -0
  55. package/dist/literal-acceptance/evaluate.d.ts +47 -0
  56. package/dist/literal-acceptance/evaluate.js +193 -0
  57. package/dist/literal-acceptance/index.d.ts +12 -0
  58. package/dist/literal-acceptance/index.js +12 -0
  59. package/dist/literal-acceptance/run.d.ts +38 -0
  60. package/dist/literal-acceptance/run.js +216 -0
  61. package/dist/literal-acceptance/safety.d.ts +24 -0
  62. package/dist/literal-acceptance/safety.js +251 -0
  63. package/dist/literal-acceptance/types.d.ts +82 -0
  64. package/dist/literal-acceptance/types.js +26 -0
  65. package/dist/policy/ac-pass-banking.d.ts +58 -0
  66. package/dist/policy/ac-pass-banking.js +150 -0
  67. package/dist/policy/ceremony-dial.d.ts +96 -11
  68. package/dist/policy/ceremony-dial.js +250 -23
  69. package/dist/policy/index.d.ts +2 -0
  70. package/dist/policy/index.js +16 -1
  71. package/dist/policy/merge-approval-head.d.ts +129 -0
  72. package/dist/policy/merge-approval-head.js +461 -0
  73. package/dist/policy/require-human-merge.d.ts +5 -0
  74. package/dist/policy/require-human-merge.js +5 -0
  75. package/dist/pr-merge-readiness/ci-gate.d.ts +20 -3
  76. package/dist/pr-merge-readiness/ci-gate.js +65 -5
  77. package/dist/pr-merge-readiness/compute.d.ts +13 -0
  78. package/dist/pr-merge-readiness/compute.js +99 -14
  79. package/dist/pr-merge-readiness/gh.d.ts +49 -0
  80. package/dist/pr-merge-readiness/gh.js +268 -0
  81. package/dist/pr-merge-readiness/index.d.ts +2 -2
  82. package/dist/pr-merge-readiness/index.js +2 -2
  83. package/dist/pr-merge-readiness/test-gh-fixtures.helpers.js +4 -0
  84. package/dist/pr-wait-mergeable/cascade.d.ts +11 -0
  85. package/dist/pr-wait-mergeable/cascade.js +115 -1
  86. package/dist/pr-wait-mergeable/main.d.ts +4 -0
  87. package/dist/pr-wait-mergeable/main.js +4 -0
  88. package/dist/pr-wait-mergeable/types.d.ts +3 -1
  89. package/dist/pr-wait-mergeable/wrappers.d.ts +6 -1
  90. package/dist/pr-wait-mergeable/wrappers.js +7 -1
  91. package/dist/preflight/evaluate.d.ts +15 -1
  92. package/dist/preflight/evaluate.js +33 -2
  93. package/dist/preflight-cache/evaluate.d.ts +3 -0
  94. package/dist/preflight-cache/evaluate.js +3 -0
  95. package/dist/product-first-done-gate/acceptance.d.ts +25 -0
  96. package/dist/product-first-done-gate/acceptance.js +247 -0
  97. package/dist/product-first-done-gate/check-mode.d.ts +45 -0
  98. package/dist/product-first-done-gate/check-mode.js +148 -0
  99. package/dist/product-first-done-gate/evaluate.d.ts +50 -0
  100. package/dist/product-first-done-gate/evaluate.js +255 -0
  101. package/dist/product-first-done-gate/index.d.ts +11 -0
  102. package/dist/product-first-done-gate/index.js +11 -0
  103. package/dist/product-first-done-gate/types.d.ts +64 -0
  104. package/dist/product-first-done-gate/types.js +61 -0
  105. package/dist/render/framework-commands.js +4 -0
  106. package/dist/run-summary/emit.d.ts +56 -0
  107. package/dist/run-summary/emit.js +171 -0
  108. package/dist/run-summary/index.d.ts +4 -0
  109. package/dist/run-summary/index.js +4 -0
  110. package/dist/run-summary/path.d.ts +25 -0
  111. package/dist/run-summary/path.js +78 -0
  112. package/dist/run-summary/types.d.ts +76 -0
  113. package/dist/run-summary/types.js +21 -0
  114. package/dist/scope/acceptance-evidence.d.ts +110 -0
  115. package/dist/scope/acceptance-evidence.js +422 -0
  116. package/dist/scope/coverage-map.d.ts +98 -0
  117. package/dist/scope/coverage-map.js +558 -0
  118. package/dist/scope/decompose.d.ts +5 -0
  119. package/dist/scope/decompose.js +134 -11
  120. package/dist/scope/index.d.ts +3 -0
  121. package/dist/scope/index.js +3 -0
  122. package/dist/scope/parent-lineage.d.ts +125 -0
  123. package/dist/scope/parent-lineage.js +626 -0
  124. package/dist/scope/transition.d.ts +8 -0
  125. package/dist/scope/transition.js +61 -2
  126. package/dist/session/ac-pass-banking.d.ts +221 -0
  127. package/dist/session/ac-pass-banking.js +761 -0
  128. package/dist/session/active-cli.d.ts +79 -0
  129. package/dist/session/active-cli.js +382 -0
  130. package/dist/session/deposit-sha.d.ts +49 -0
  131. package/dist/session/deposit-sha.js +121 -0
  132. package/dist/session/effort-budget.d.ts +136 -0
  133. package/dist/session/effort-budget.js +352 -0
  134. package/dist/session/index.d.ts +7 -0
  135. package/dist/session/index.js +7 -0
  136. package/dist/session/orientation-compression.d.ts +127 -0
  137. package/dist/session/orientation-compression.js +425 -0
  138. package/dist/session/orientation-state.d.ts +29 -0
  139. package/dist/session/orientation-state.js +85 -0
  140. package/dist/session/session-start.d.ts +31 -0
  141. package/dist/session/session-start.js +228 -2
  142. package/dist/session/toolchain-preflight.d.ts +64 -0
  143. package/dist/session/toolchain-preflight.js +151 -0
  144. package/dist/session/verify-session-ritual.d.ts +14 -0
  145. package/dist/session/verify-session-ritual.js +33 -0
  146. package/dist/story-ready/evaluate.d.ts +11 -0
  147. package/dist/story-ready/evaluate.js +41 -3
  148. package/dist/triage/actions/candidates-log.d.ts +1 -2
  149. package/dist/triage/actions/candidates-log.js +37 -6
  150. package/dist/triage/bootstrap/gitignore.d.ts +1 -1
  151. package/dist/triage/bootstrap/gitignore.js +8 -2
  152. package/dist/triage/bootstrap/index.js +15 -3
  153. package/dist/triage/classify/index.d.ts +1 -0
  154. package/dist/triage/classify/index.js +2 -0
  155. package/dist/triage/classify/label-mirror.js +16 -0
  156. package/dist/triage/classify/mirror-discovery-tip.d.ts +95 -0
  157. package/dist/triage/classify/mirror-discovery-tip.js +234 -0
  158. package/dist/triage/reconcile/reconcile.js +28 -6
  159. package/dist/triage/summary/index.js +12 -4
  160. package/dist/triage/welcome/default-mode.js +16 -0
  161. package/dist/ts-check-lane/run-lane.js +21 -4
  162. package/dist/vbrief-validate/conformance.js +7 -0
  163. package/dist/vitest-runner/coverage-debt-teardown.js +16 -4
  164. package/dist/xbrief-migrate/migrate-project.d.ts +4 -0
  165. package/dist/xbrief-migrate/migrate-project.js +92 -3
  166. package/package.json +15 -3
@@ -9,6 +9,11 @@ export type CheckGateSpec = string | {
9
9
  readonly task: string;
10
10
  readonly args?: readonly string[];
11
11
  };
12
+ /**
13
+ * Product-first AC gate (#3284): always first; soft-missing when no active
14
+ * xBRIEF so framework self-check is not deadlocked without a story.
15
+ */
16
+ export declare const PRODUCT_FIRST_AC_GATE: CheckGateSpec;
12
17
  export declare function checkGateId(spec: CheckGateSpec): string;
13
18
  /** Args for `task … --taskfile <path>` (optional `--` + public CLI flags). */
14
19
  export declare function checkGateSpawnArgs(spec: CheckGateSpec, taskfilePath: string): string[];
@@ -26,11 +31,12 @@ export declare function isSuiteCheckGate(spec: CheckGateSpec | string): boolean;
26
31
  */
27
32
  export declare function isFastBeforeSlowOrder(gates: readonly CheckGateSpec[]): boolean;
28
33
  /**
29
- * Framework-source check composition (#1713 / #3188).
34
+ * Framework-source check composition (#1713 / #3188 / #3284).
30
35
  *
31
- * Order contract: cheap preflight gates first; `ts:check-lane` (lint+build+
32
- * vitest coverage suite) last so a stale cache / orphan-active / branch miss
33
- * fails in seconds without starting the suite.
36
+ * Order contract:
37
+ * 1. Product AC first (fail-fast; never skippable when commands exist) #3284
38
+ * 2. Cheap hygiene preflight #3188
39
+ * 3. `ts:check-lane` suite last
34
40
  */
35
41
  export declare const FRAMEWORK_CHECK_GATES: readonly CheckGateSpec[];
36
42
  export declare const CONSUMER_CHECK_GATES: readonly CheckGateSpec[];
@@ -1,4 +1,13 @@
1
1
  /** Gate execution order mirrors Taskfile.yml check targets (#1713 dogfood). */
2
+ import { PRODUCT_AC_GATE_ID } from "../product-first-done-gate/types.js";
3
+ /**
4
+ * Product-first AC gate (#3284): always first; soft-missing when no active
5
+ * xBRIEF so framework self-check is not deadlocked without a story.
6
+ */
7
+ export const PRODUCT_FIRST_AC_GATE = {
8
+ task: PRODUCT_AC_GATE_ID,
9
+ args: ["--soft-missing-xbrief"],
10
+ };
2
11
  export function checkGateId(spec) {
3
12
  return typeof spec === "string" ? spec : spec.task;
4
13
  }
@@ -39,13 +48,16 @@ export function isFastBeforeSlowOrder(gates) {
39
48
  return true;
40
49
  }
41
50
  /**
42
- * Framework-source check composition (#1713 / #3188).
51
+ * Framework-source check composition (#1713 / #3188 / #3284).
43
52
  *
44
- * Order contract: cheap preflight gates first; `ts:check-lane` (lint+build+
45
- * vitest coverage suite) last so a stale cache / orphan-active / branch miss
46
- * fails in seconds without starting the suite.
53
+ * Order contract:
54
+ * 1. Product AC first (fail-fast; never skippable when commands exist) #3284
55
+ * 2. Cheap hygiene preflight #3188
56
+ * 3. `ts:check-lane` suite last
47
57
  */
48
58
  export const FRAMEWORK_CHECK_GATES = [
59
+ // --- Product-first done-gate (#3284) — AC before any hygiene ---
60
+ PRODUCT_FIRST_AC_GATE,
49
61
  // --- Fast preflight (seconds–few min) — #3188 ---
50
62
  "verify:branch",
51
63
  "verify:encoding",
@@ -89,7 +101,9 @@ export const FRAMEWORK_CHECK_GATES = [
89
101
  "ts:check-lane",
90
102
  ];
91
103
  export const CONSUMER_CHECK_GATES = [
92
- // Cheap lifecycle / policy first (no suite co-list today; keep fail-fast order)
104
+ // Product-first: stated AC before hygiene (#3284)
105
+ PRODUCT_FIRST_AC_GATE,
106
+ // Cheap lifecycle / policy second (no suite co-list today; keep fail-fast order)
93
107
  "verify:branch",
94
108
  "verify:cache-fresh",
95
109
  "verify:wip-cap",
@@ -1,6 +1,7 @@
1
- export { dispatchCachedTaskCheck } from "./cached-orchestrator.js";
1
+ export { type CachedCheckOptions, dispatchCachedTaskCheck } from "./cached-orchestrator.js";
2
2
  export { CHECK_GRAPH_REQUIRED_NAMESPACES, CONSUMER_GATE_INTEGRITY_RECOVERY, type ConsumerGateIntegrityFinding, type ConsumerGateIntegrityResult, type ConsumerGateIntegritySeams, checkGraphOptionalIncludeViolations, evaluateConsumerGateIntegrity, formatConsumerGateIntegrityFailure, gateLocalName, gateNamespace, includeTaskfileRel, parseTaskfileIncludes, requiredNamespacesForGates, taskDefinedInTaskfileYaml, } from "./consumer-gate-integrity.js";
3
- export { type CheckGateSpec, CONSUMER_CHECK_GATES, checkGateId, checkGateSpawnArgs, FRAMEWORK_CHECK_GATES, gatesForCheckTarget, isFastBeforeSlowOrder, isSuiteCheckGate, SUITE_CHECK_GATE_IDS, } from "./gate-lists.js";
3
+ export { type CheckGateSpec, CONSUMER_CHECK_GATES, checkGateId, checkGateSpawnArgs, FRAMEWORK_CHECK_GATES, gatesForCheckTarget, isFastBeforeSlowOrder, isSuiteCheckGate, PRODUCT_FIRST_AC_GATE, SUITE_CHECK_GATE_IDS, } from "./gate-lists.js";
4
+ export { extractGateCause, formatDegradedSkipReport, formatNamedCauseFailure, type NamedCauseMessage, remedyForGate, } from "./named-cause.js";
4
5
  export type { CheckOrchestratorOptions, CheckOrchestratorSeams } from "./orchestrator.js";
5
6
  export { dispatchTaskCheck, isFrameworkRepoRoot, isFrameworkSourceContext, resolveCheckTarget, } from "./orchestrator.js";
6
7
  export { detectTestRunner, type RunnerDetectResult, runnerDetectionTable, type TestRunnerKind, } from "./runner-detect.js";
@@ -1,6 +1,7 @@
1
1
  export { dispatchCachedTaskCheck } from "./cached-orchestrator.js";
2
2
  export { CHECK_GRAPH_REQUIRED_NAMESPACES, CONSUMER_GATE_INTEGRITY_RECOVERY, checkGraphOptionalIncludeViolations, evaluateConsumerGateIntegrity, formatConsumerGateIntegrityFailure, gateLocalName, gateNamespace, includeTaskfileRel, parseTaskfileIncludes, requiredNamespacesForGates, taskDefinedInTaskfileYaml, } from "./consumer-gate-integrity.js";
3
- export { CONSUMER_CHECK_GATES, checkGateId, checkGateSpawnArgs, FRAMEWORK_CHECK_GATES, gatesForCheckTarget, isFastBeforeSlowOrder, isSuiteCheckGate, SUITE_CHECK_GATE_IDS, } from "./gate-lists.js";
3
+ export { CONSUMER_CHECK_GATES, checkGateId, checkGateSpawnArgs, FRAMEWORK_CHECK_GATES, gatesForCheckTarget, isFastBeforeSlowOrder, isSuiteCheckGate, PRODUCT_FIRST_AC_GATE, SUITE_CHECK_GATE_IDS, } from "./gate-lists.js";
4
+ export { extractGateCause, formatDegradedSkipReport, formatNamedCauseFailure, remedyForGate, } from "./named-cause.js";
4
5
  export { dispatchTaskCheck, isFrameworkRepoRoot, isFrameworkSourceContext, resolveCheckTarget, } from "./orchestrator.js";
5
6
  export { detectTestRunner, runnerDetectionTable, } from "./runner-detect.js";
6
7
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Named-cause + remedy formatting for check gate failures (#3282).
3
+ *
4
+ * Gate failures must never be bare exit 1: report gate name, cause, and remedy
5
+ * without embedding env values.
6
+ */
7
+ export interface NamedCauseMessage {
8
+ readonly gateId: string;
9
+ readonly exitCode: number;
10
+ readonly cause: string;
11
+ readonly remedy: string;
12
+ readonly lines: readonly string[];
13
+ }
14
+ /**
15
+ * Extract a short cause from gate stdout/stderr without leaking env values.
16
+ * Strips lines that look like KEY=value assignments.
17
+ */
18
+ export declare function extractGateCause(stdout: string, stderr: string, exitCode: number, spawnError?: string): string;
19
+ export declare function remedyForGate(gateId: string, cause: string): string;
20
+ /**
21
+ * Format named-cause failure lines for a single gate.
22
+ */
23
+ export declare function formatNamedCauseFailure(input: {
24
+ readonly gateId: string;
25
+ readonly exitCode: number;
26
+ readonly stdout?: string;
27
+ readonly stderr?: string;
28
+ readonly spawnError?: string;
29
+ }): NamedCauseMessage;
30
+ /**
31
+ * Format degraded-mode skip report (which gates skipped and why).
32
+ */
33
+ export declare function formatDegradedSkipReport(input: {
34
+ readonly reason: string;
35
+ readonly skipped: readonly {
36
+ id: string;
37
+ cause: string;
38
+ remedy: string;
39
+ }[];
40
+ readonly ran?: readonly string[];
41
+ readonly failed?: readonly string[];
42
+ /** Default 2 = config/environment (never green-pass skipped required gates). */
43
+ readonly exitCode?: number;
44
+ }): readonly string[];
45
+ //# sourceMappingURL=named-cause.d.ts.map
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Named-cause + remedy formatting for check gate failures (#3282).
3
+ *
4
+ * Gate failures must never be bare exit 1: report gate name, cause, and remedy
5
+ * without embedding env values.
6
+ */
7
+ /** Per-gate remedy hints (static; no env interpolation). */
8
+ const GATE_REMEDIES = {
9
+ "verify:branch": "Create a feature branch (`git switch -c feat/<name>`) or set plan.policy.allowDirectCommitsToMaster with confirmation",
10
+ "verify:encoding": "Fix non-ASCII / encoding issues flagged by the gate; re-run task verify:encoding",
11
+ "verify:cache-fresh": "Run task cache:fetch-all or task triage:bootstrap to refresh the cache",
12
+ "verify:orphan-active": "Complete or cancel active xBRIEFs whose issues are closed / PRs merged (task scope:complete / scope:cancel)",
13
+ "verify:wip-cap": "Demote stale pending scopes (task scope:demote) or raise plan.policy.wipCap deliberately",
14
+ doctor: "Run task doctor and follow the named recovery steps",
15
+ "toolchain:check": "Install missing maintainer tools reported by the gate (go, uv, git, gh, node, pnpm)",
16
+ "toolchain:check-consumer": "Install missing consumer tools: go-task, git, gh, node, pnpm (corepack enable && corepack prepare pnpm@latest --activate)",
17
+ "ts:check-lane": "Fix lint/type/test failures; re-run task ts:check-lane",
18
+ "vbrief:validate": "Fix xBRIEF/vBRIEF schema errors reported by the gate",
19
+ "verify-strategy-output": "Re-run strategy output or fix non-conformant scope filenames / PROJECT-DEFINITION",
20
+ "verify:test-boundary": "Move tests to the allowed placement or update plan.policy test-boundary allowlist",
21
+ "verify:scope-provenance": "Record approved scope provenance for the failing paths",
22
+ "verify:consumer-check-contract": "Align consumer Taskfile includes with the required gate graph",
23
+ "verify:forward-coverage": "Add tests covering new source files (task verify:forward-coverage)",
24
+ "verify:scm-boundary": "Move SCM mutations off GraphQL-heavy paths or wait for rate-limit reset",
25
+ "verify:license-sync": "Sync LICENSE / package license fields",
26
+ "verify:agents-md-budget": "Trim AGENTS.md managed section or raise plan.policy.agentsMdBudget deliberately",
27
+ };
28
+ const SPAWN_ERROR_REMEDY = "Install go-task (https://taskfile.dev/installation/) and ensure `task` is on PATH; then re-run task check";
29
+ /**
30
+ * Extract a short cause from gate stdout/stderr without leaking env values.
31
+ * Strips lines that look like KEY=value assignments.
32
+ */
33
+ export function extractGateCause(stdout, stderr, exitCode, spawnError) {
34
+ if (spawnError !== undefined && spawnError.length > 0) {
35
+ // Normalize common missing-binary messages without path dumps.
36
+ if (/ENOENT|not found|not recognized/i.test(spawnError)) {
37
+ return "task binary not found on PATH (cannot spawn go-task)";
38
+ }
39
+ return sanitizeCauseLine(spawnError);
40
+ }
41
+ const combined = `${stderr}\n${stdout}`
42
+ .split(/\r?\n/)
43
+ .map((l) => l.trim())
44
+ .filter((l) => l.length > 0);
45
+ for (const line of combined) {
46
+ if (looksLikeEnvLeak(line))
47
+ continue;
48
+ if (line.startsWith("check:"))
49
+ continue;
50
+ return sanitizeCauseLine(line);
51
+ }
52
+ return `gate exited ${exitCode} without a diagnostic message`;
53
+ }
54
+ function looksLikeEnvLeak(line) {
55
+ // Avoid echoing DEFT_*= or generic env dumps.
56
+ if (/^[A-Z][A-Z0-9_]*=/.test(line))
57
+ return true;
58
+ if (/\bDEFT_[A-Z0-9_]+\b/.test(line) && line.includes("="))
59
+ return true;
60
+ return false;
61
+ }
62
+ function sanitizeCauseLine(line) {
63
+ // Cap length; collapse absolute home paths lightly.
64
+ let out = line.replace(/\r/g, "").trim();
65
+ if (out.length > 240) {
66
+ out = `${out.slice(0, 237)}...`;
67
+ }
68
+ return out;
69
+ }
70
+ export function remedyForGate(gateId, cause) {
71
+ if (/task binary not found|cannot spawn go-task/i.test(cause)) {
72
+ return SPAWN_ERROR_REMEDY;
73
+ }
74
+ if (/pnpm binary not found|pnpm: NOT FOUND/i.test(cause)) {
75
+ return "Enable pnpm: corepack enable && corepack prepare pnpm@latest --activate";
76
+ }
77
+ return (GATE_REMEDIES[gateId] ??
78
+ `Re-run the gate for details: task ${gateId} (or task check); fix the reported product/process defect`);
79
+ }
80
+ /**
81
+ * Format named-cause failure lines for a single gate.
82
+ */
83
+ export function formatNamedCauseFailure(input) {
84
+ const cause = extractGateCause(input.stdout ?? "", input.stderr ?? "", input.exitCode, input.spawnError);
85
+ const remedy = remedyForGate(input.gateId, cause);
86
+ const lines = [
87
+ `check: gate ${input.gateId} failed (exit ${input.exitCode})`,
88
+ ` cause: ${cause}`,
89
+ ` remedy: ${remedy}`,
90
+ ];
91
+ return {
92
+ gateId: input.gateId,
93
+ exitCode: input.exitCode,
94
+ cause,
95
+ remedy,
96
+ lines,
97
+ };
98
+ }
99
+ /**
100
+ * Format degraded-mode skip report (which gates skipped and why).
101
+ */
102
+ export function formatDegradedSkipReport(input) {
103
+ const exitCode = input.exitCode ?? 2;
104
+ const lines = [
105
+ `check: degraded mode — ${input.reason}`,
106
+ `check: skipped ${input.skipped.length} gate(s) due to missing framework toolchain (#3282):`,
107
+ ];
108
+ for (const gate of input.skipped) {
109
+ lines.push(` - ${gate.id}: cause: ${gate.cause}; remedy: ${gate.remedy}`);
110
+ }
111
+ if (input.ran !== undefined && input.ran.length > 0) {
112
+ lines.push(`check: ran: ${input.ran.join(", ")}`);
113
+ }
114
+ if (input.failed !== undefined && input.failed.length > 0) {
115
+ lines.push(`check: failed: ${input.failed.join(", ")}`);
116
+ }
117
+ lines.push(`check: exit ${exitCode} (degraded/config) — skipped required gates are not a green pass; ` +
118
+ "install missing tooling (see remedies above) and re-run task check");
119
+ return lines;
120
+ }
121
+ //# sourceMappingURL=named-cause.js.map
@@ -57,7 +57,12 @@ export function dispatchTaskCheck(frameworkRoot, projectRoot, seams = {}) {
57
57
  timeoutMs: seams.timeoutMs,
58
58
  });
59
59
  if (result.error !== undefined) {
60
- process.stderr.write(`check: failed to invoke task: ${result.error.message}\n`);
60
+ // #3282: named cause + remedy instead of bare spawn failure.
61
+ const detail = result.error.message;
62
+ const missingTask = /ENOENT|not found|not recognized/i.test(detail);
63
+ process.stderr.write(`check: gate ${target} failed (exit 2)\n` +
64
+ ` cause: ${missingTask ? "task binary not found on PATH (cannot spawn go-task)" : detail}\n` +
65
+ " remedy: Install go-task (https://taskfile.dev/installation/) and ensure `task` is on PATH; then re-run task check\n");
61
66
  return 2;
62
67
  }
63
68
  if (result.signal === "SIGTERM" && result.status === null && seams.timeoutMs !== undefined) {
@@ -1,9 +1,42 @@
1
+ import type { XbriefSchemaDistance } from "../staleness-tickler/types.js";
1
2
  import type { CheckResult } from "./types.js";
3
+ /** Remediation verb for project envelope behind-major (#2971 / #3243 / #3236). */
4
+ export declare const XBRIEF_ENVELOPE_MIGRATE_COMMAND: "deft migrate:xbrief";
5
+ /** Doctor check name for envelope major mismatch (Q5 Option 2, #3243). */
6
+ export declare const XBRIEF_ENVELOPE_MAJOR_CHECK: "xbrief-envelope-version";
2
7
  export interface CheckSeams {
3
8
  readonly readText?: (path: string) => string | null;
4
9
  readonly isFile?: (path: string) => boolean;
5
10
  readonly isDir?: (path: string) => boolean;
11
+ /** List directory entries; throws on enum failure (fail-closed for live lifecycle dirs). */
12
+ readonly readdir?: (path: string) => string[];
6
13
  }
14
+ /** One scanned project envelope and its schema distance vs the framework target. */
15
+ export interface XbriefEnvelopeScanEntry {
16
+ readonly relativePath: string;
17
+ readonly declaredVersion: string | null;
18
+ readonly distance: XbriefSchemaDistance;
19
+ }
20
+ /**
21
+ * Scan live project xbrief envelopes (PROJECT-DEFINITION + pending/active) for
22
+ * schema distance vs the installed framework envelope major (#3243). Complements
23
+ * #2971 PROJECT-DEFINITION-only probe; remediation aligns with migrate hybrid
24
+ * rewrite (#3236).
25
+ */
26
+ export declare function scanXbriefEnvelopeVersions(projectRoot: string, seams?: CheckSeams, targetVersion?: string): {
27
+ readonly targetVersion: string;
28
+ readonly entries: readonly XbriefEnvelopeScanEntry[];
29
+ readonly worstDistance: XbriefSchemaDistance | null;
30
+ readonly behindMajor: readonly XbriefEnvelopeScanEntry[];
31
+ };
32
+ /**
33
+ * Fail closed when any scanned project xBRIEF envelope declares a major behind
34
+ * the framework target (#3243 / epic #3237 Q5 Option 2). Behind-minor does not
35
+ * fail this check. Remediation: `deft migrate:xbrief` (rewrites hybrid 0.6 on
36
+ * already-xbrief trees — #3236). Distinct from `stale-xbrief-schema-deposit`
37
+ * which routes schema-only drift to `directive update`.
38
+ */
39
+ export declare function checkXbriefEnvelopeMajorVersion(projectRoot: string, seams?: CheckSeams): CheckResult;
7
40
  export declare function checkQuickStartResolves(projectRoot: string, installRoot: string | null, seams?: CheckSeams): CheckResult;
8
41
  export declare function checkSkillPathsResolve(projectRoot: string, agentsMdText: string, seams?: CheckSeams): CheckResult;
9
42
  export declare function checkManifestAgreement(projectRoot: string, installRoot: string | null, seams?: CheckSeams): CheckResult;
@@ -60,6 +93,17 @@ export declare function checkGitignoreCoverage(projectRoot: string, seams?: Chec
60
93
  * Decided-off is quiet; dismiss-with-reason is pass with reason in detail.
61
94
  * Invalid typed blocks resolve fail-closed and surface via source=default-on-error.
62
95
  */
96
+ /**
97
+ * Fail closed when completed/ plan.status disagrees with the folder (#3242 AC1 / epic #3237 Q4).
98
+ * Open plan.items under completed/ are reported by `checkCompletedOpenItems` (exit-exempt
99
+ * until historical corpora are backfilled; scope:complete enforces items hard).
100
+ */
101
+ export declare function checkCompletedLifecycleConsistency(projectRoot: string): CheckResult;
102
+ /**
103
+ * Surface non-terminal plan.items under completed/ (#3242). Exit-exempt so
104
+ * historical pre-#2862 corpora do not red-light doctor; scope:complete fails closed.
105
+ */
106
+ export declare function checkCompletedOpenItems(projectRoot: string): CheckResult;
63
107
  export declare function checkCoverageCheckResumePolicy(projectRoot: string): CheckResult;
64
108
  export declare function deriveExitCode(checks: readonly CheckResult[], errors: readonly string[]): number;
65
109
  export declare function runChecksImpl(projectRoot: string, seams?: CheckSeams & {