@deftai/directive-core 0.101.0 → 0.103.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 (75) hide show
  1. package/dist/authz/classify.js +97 -8
  2. package/dist/check/cached-orchestrator.d.ts +4 -0
  3. package/dist/check/cached-orchestrator.js +70 -5
  4. package/dist/check/cli-native-gates.d.ts +43 -0
  5. package/dist/check/cli-native-gates.js +84 -0
  6. package/dist/check/index.d.ts +1 -0
  7. package/dist/check/index.js +1 -0
  8. package/dist/check/named-cause.js +10 -0
  9. package/dist/doctor/checks.d.ts +5 -6
  10. package/dist/doctor/checks.js +13 -56
  11. package/dist/eval/later-graduation.d.ts +39 -0
  12. package/dist/eval/later-graduation.js +91 -0
  13. package/dist/eval/report.d.ts +6 -0
  14. package/dist/eval/report.js +27 -8
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.js +1 -0
  17. package/dist/init-deposit/hygiene.d.ts +7 -1
  18. package/dist/init-deposit/hygiene.js +11 -3
  19. package/dist/init-deposit/scaffold.d.ts +12 -0
  20. package/dist/init-deposit/scaffold.js +81 -8
  21. package/dist/intake/issue-ingest.js +42 -0
  22. package/dist/policy/ceremony-dial-escalation.d.ts +52 -0
  23. package/dist/policy/ceremony-dial-escalation.js +92 -0
  24. package/dist/policy/ceremony-dial.d.ts +3 -1
  25. package/dist/policy/ceremony-dial.js +52 -1
  26. package/dist/policy/check-resume.d.ts +9 -38
  27. package/dist/policy/check-resume.js +18 -156
  28. package/dist/policy/coverage-debt.d.ts +18 -37
  29. package/dist/policy/coverage-debt.js +38 -147
  30. package/dist/policy/index.d.ts +1 -1
  31. package/dist/policy/index.js +1 -1
  32. package/dist/product-first-done-gate/acceptance.js +22 -0
  33. package/dist/product-first-done-gate/empty-resolution.d.ts +26 -0
  34. package/dist/product-first-done-gate/empty-resolution.js +38 -0
  35. package/dist/product-first-done-gate/evaluate.d.ts +40 -2
  36. package/dist/product-first-done-gate/evaluate.js +253 -61
  37. package/dist/product-first-done-gate/index.d.ts +2 -1
  38. package/dist/product-first-done-gate/index.js +2 -1
  39. package/dist/product-first-done-gate/types.d.ts +3 -0
  40. package/dist/product-first-done-gate/types.js +0 -7
  41. package/dist/run-summary/emit.d.ts +11 -1
  42. package/dist/run-summary/emit.js +48 -2
  43. package/dist/run-summary/index.d.ts +2 -1
  44. package/dist/run-summary/index.js +2 -1
  45. package/dist/run-summary/path.d.ts +1 -1
  46. package/dist/run-summary/path.js +1 -1
  47. package/dist/run-summary/share.d.ts +25 -0
  48. package/dist/run-summary/share.js +106 -0
  49. package/dist/run-summary/types.d.ts +60 -2
  50. package/dist/run-summary/types.js +7 -0
  51. package/dist/scope/acceptance-activate-gate.d.ts +23 -0
  52. package/dist/scope/acceptance-activate-gate.js +70 -0
  53. package/dist/scope/index.d.ts +1 -0
  54. package/dist/scope/index.js +1 -0
  55. package/dist/scope/transition.js +5 -0
  56. package/dist/session/index.d.ts +0 -1
  57. package/dist/session/index.js +0 -1
  58. package/dist/session/orientation-compression.js +19 -9
  59. package/dist/session/session-start.d.ts +6 -0
  60. package/dist/session/session-start.js +44 -22
  61. package/dist/session/toolchain-preflight.d.ts +15 -0
  62. package/dist/session/toolchain-preflight.js +65 -5
  63. package/dist/verify-ac/clauses.d.ts +51 -0
  64. package/dist/verify-ac/clauses.js +490 -0
  65. package/dist/verify-ac/evaluate.d.ts +73 -0
  66. package/dist/verify-ac/evaluate.js +167 -0
  67. package/dist/verify-ac/flag.d.ts +35 -0
  68. package/dist/verify-ac/flag.js +104 -0
  69. package/dist/verify-ac/index.d.ts +10 -0
  70. package/dist/verify-ac/index.js +10 -0
  71. package/package.json +7 -3
  72. package/dist/policy/coverage-check-resume-presets.d.ts +0 -46
  73. package/dist/policy/coverage-check-resume-presets.js +0 -228
  74. package/dist/session/coverage-check-resume-nudge.d.ts +0 -34
  75. package/dist/session/coverage-check-resume-nudge.js +0 -66
@@ -1,228 +0,0 @@
1
- /**
2
- * Bundled presets for coverageDebt + checkResume (#3189).
3
- *
4
- * One project decision (not five micro-toggles in v1).
5
- * Later does not write decided; Strict / Hatch-aware / dismiss-with-reason do.
6
- *
7
- * Both fields are written in a single PROJECT-DEFINITION mutation lock so a
8
- * partial decision (coverageDebt decided, checkResume still unset) cannot
9
- * persist after a mid-write failure.
10
- */
11
- import { readFileSync } from "node:fs";
12
- import { atomicWriteProjectDefinition, projectDefinitionMutationLock, } from "../vbrief-build/project-definition-io.js";
13
- import { CHECK_RESUME_CI_TRUSTS_LOCAL_STAMP_V1, formatCheckResumeStatusLine, resolveCheckResume, resolveCheckResumeFromTypedBlock, } from "./check-resume.js";
14
- import { DEFAULT_COVERAGE_DEBT_AUTO_FILE, formatCoverageDebtStatusLine, resolveCoverageDebt, resolveCoverageDebtFromTypedBlock, } from "./coverage-debt.js";
15
- import { migrateLegacyPolicyKey, PLAN_POLICY_KEY } from "./plan-extensions.js";
16
- import { policyColonInvocation } from "./policy-invocation.js";
17
- import { appendAuditLog, projectDefinitionPath } from "./resolve.js";
18
- export const COVERAGE_CHECK_RESUME_PRESETS = ["strict", "hatch-aware"];
19
- /** True when either policy is still unset (coupled v1 nag). */
20
- export function isCoverageCheckResumeUndecided(projectRoot) {
21
- const debt = resolveCoverageDebt(projectRoot);
22
- const resume = resolveCheckResume(projectRoot);
23
- return debt.status === "unset" || resume.status === "unset";
24
- }
25
- /**
26
- * Atomically write both coverageDebt and checkResume under one mutation lock.
27
- */
28
- function writeCoverageCheckResumeBundle(projectRoot, input) {
29
- const path = projectDefinitionPath(projectRoot);
30
- try {
31
- const writeResult = projectDefinitionMutationLock(projectRoot, () => {
32
- const parsed = JSON.parse(readFileSync(path, { encoding: "utf8" }));
33
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
34
- throw new Error(`PROJECT-DEFINITION at ${path} top-level value is not a JSON object`);
35
- }
36
- const data = parsed;
37
- if (typeof data.plan !== "object" || data.plan === null || Array.isArray(data.plan)) {
38
- if (data.plan === undefined) {
39
- data.plan = {};
40
- }
41
- else {
42
- throw new Error("PROJECT-DEFINITION 'plan' is not an object");
43
- }
44
- }
45
- const plan = data.plan;
46
- migrateLegacyPolicyKey(plan);
47
- const existingPolicy = plan[PLAN_POLICY_KEY];
48
- if (typeof existingPolicy !== "object" ||
49
- existingPolicy === null ||
50
- Array.isArray(existingPolicy)) {
51
- if (existingPolicy === undefined) {
52
- plan[PLAN_POLICY_KEY] = {};
53
- }
54
- else {
55
- throw new Error("plan.policy is not an object");
56
- }
57
- }
58
- const policyBlock = plan[PLAN_POLICY_KEY];
59
- const previousDebt = policyBlock.coverageDebt;
60
- const previousResume = policyBlock.checkResume;
61
- const autoFile = input.mode === "hatch" ? (input.autoFile ?? DEFAULT_COVERAGE_DEBT_AUTO_FILE) : false;
62
- const dismissReason = typeof input.dismissReason === "string" && input.dismissReason.trim().length > 0
63
- ? input.dismissReason.trim()
64
- : null;
65
- const nextDebt = {
66
- status: "decided",
67
- mode: input.mode,
68
- autoFile,
69
- dismissReason,
70
- };
71
- const nextResume = {
72
- status: "decided",
73
- localStamp: input.localStamp,
74
- ciTrustsLocalStamp: CHECK_RESUME_CI_TRUSTS_LOCAL_STAMP_V1,
75
- dismissReason,
76
- };
77
- const prevDebt = resolveCoverageDebtFromTypedBlock(previousDebt);
78
- const prevResume = resolveCheckResumeFromTypedBlock(previousResume);
79
- const changedFlag = prevDebt.status !== nextDebt.status ||
80
- prevDebt.mode !== nextDebt.mode ||
81
- prevDebt.autoFile !== nextDebt.autoFile ||
82
- prevDebt.dismissReason !== nextDebt.dismissReason ||
83
- prevResume.status !== nextResume.status ||
84
- prevResume.localStamp !== nextResume.localStamp ||
85
- prevResume.dismissReason !== nextResume.dismissReason;
86
- // Single write of both keys — no partial decide on mid-failure.
87
- policyBlock.coverageDebt = nextDebt;
88
- policyBlock.checkResume = nextResume;
89
- if (changedFlag) {
90
- atomicWriteProjectDefinition(path, data);
91
- }
92
- let auditOk = true;
93
- // Audit after durable write: failure must not reverse the decision, but
94
- // the operator report must not claim the audit trail was updated.
95
- try {
96
- const note = input.note.replace(/\n/g, " ").replace(/\r/g, " ");
97
- appendAuditLog(projectRoot, [
98
- `actor=${input.actor}`,
99
- `preset=${input.preset}`,
100
- "coverageDebt.status=decided",
101
- `mode=${nextDebt.mode}`,
102
- `autoFile=${String(nextDebt.autoFile)}`,
103
- "checkResume.status=decided",
104
- `localStamp=${nextResume.localStamp}`,
105
- "ciTrustsLocalStamp=false",
106
- `dismissReason=${JSON.stringify(dismissReason)}`,
107
- `previousDebt=${JSON.stringify(previousDebt ?? null)}`,
108
- `previousResume=${JSON.stringify(previousResume ?? null)}`,
109
- note ? `note=${note}` : "",
110
- ]
111
- .filter(Boolean)
112
- .join(" "));
113
- }
114
- catch {
115
- auditOk = false;
116
- }
117
- return { changed: changedFlag, auditOk };
118
- });
119
- const summary = formatCoverageCheckResumeBundleStatus(projectRoot);
120
- const auditLine = writeResult.auditOk
121
- ? writeResult.changed
122
- ? " audit: meta/policy-changes.log updated."
123
- : " no-op: value already matched (audit entry still appended for trail)."
124
- : " warning: policy write succeeded but audit log append failed; decision is durable.";
125
- const lines = [
126
- `\u2713 coverageDebt+checkResume decided via preset=${input.preset} (atomic write).`,
127
- auditLine,
128
- summary,
129
- ];
130
- return {
131
- exitCode: 0,
132
- stdout: `${lines.join("\n")}\n`,
133
- changed: writeResult.changed,
134
- preset: input.preset,
135
- };
136
- }
137
- catch (err) {
138
- const message = err instanceof Error ? err.message : String(err);
139
- if (message.includes("PROJECT-DEFINITION not found") ||
140
- message.includes("ENOENT") ||
141
- message.includes("no such file")) {
142
- return {
143
- exitCode: 2,
144
- stdout: `\u274c PROJECT-DEFINITION not found under ${projectRoot}\n`,
145
- changed: false,
146
- preset: input.preset,
147
- };
148
- }
149
- return {
150
- exitCode: 2,
151
- stdout: `\u274c Config error: ${message}\n`,
152
- changed: false,
153
- preset: input.preset,
154
- };
155
- }
156
- }
157
- /**
158
- * Apply Strict: coverageDebt.mode=off, checkResume.localStamp=off, both decided.
159
- * Recommended for most apps.
160
- */
161
- export function applyStrictCoverageCheckResumePreset(projectRoot, options = {}) {
162
- return writeCoverageCheckResumeBundle(projectRoot, {
163
- mode: "off",
164
- autoFile: false,
165
- localStamp: "off",
166
- actor: options.actor ?? policyColonInvocation("coverage-check-resume-preset", " strict"),
167
- note: options.note ?? "preset=strict",
168
- preset: "strict",
169
- });
170
- }
171
- /**
172
- * Apply Hatch-aware: coverageDebt.mode=hatch autoFile=false; localStamp=on for DX.
173
- * CI still never trusts local stamps.
174
- */
175
- export function applyHatchAwareCoverageCheckResumePreset(projectRoot, options = {}) {
176
- return writeCoverageCheckResumeBundle(projectRoot, {
177
- mode: "hatch",
178
- autoFile: false,
179
- localStamp: "on",
180
- actor: options.actor ?? policyColonInvocation("coverage-check-resume-preset", " hatch-aware"),
181
- note: options.note ?? "preset=hatch-aware",
182
- preset: "hatch-aware",
183
- });
184
- }
185
- /**
186
- * Dismiss-with-reason: marks both decided as fail-closed (mode off / localStamp off)
187
- * and records the reason for policy:show / doctor visibility. Stops the session nag.
188
- */
189
- export function dismissCoverageCheckResume(projectRoot, reason, options = {}) {
190
- const trimmed = reason.trim();
191
- if (trimmed.length === 0) {
192
- return {
193
- exitCode: 1,
194
- stdout: "\u274c dismiss-with-reason requires a non-empty reason " +
195
- "(Later without a reason does not decide; re-nag next ritual).\n",
196
- changed: false,
197
- preset: "dismiss",
198
- };
199
- }
200
- return writeCoverageCheckResumeBundle(projectRoot, {
201
- mode: "off",
202
- autoFile: false,
203
- localStamp: "off",
204
- dismissReason: trimmed,
205
- actor: options.actor ?? policyColonInvocation("coverage-check-resume-dismiss"),
206
- note: options.note ?? `dismiss=${trimmed}`,
207
- preset: "dismiss",
208
- });
209
- }
210
- /**
211
- * Later: does NOT write status=decided. Caller skips for this session;
212
- * next session-start ritual nags again.
213
- */
214
- export function applyLaterCoverageCheckResumeSkip() {
215
- return {
216
- exitCode: 0,
217
- stdout: "[deft policy] coverageDebt/checkResume: Later -- not decided. " +
218
- "Fail-closed defaults remain (mode off, localStamp off, CI never trusts local stamps). " +
219
- "Next interactive session-start ritual will remind you.\n",
220
- changed: false,
221
- preset: "later",
222
- };
223
- }
224
- export function formatCoverageCheckResumeBundleStatus(projectRoot) {
225
- return (`${formatCoverageDebtStatusLine(resolveCoverageDebt(projectRoot))}\n` +
226
- `${formatCheckResumeStatusLine(resolveCheckResume(projectRoot))}`);
227
- }
228
- //# sourceMappingURL=coverage-check-resume-presets.js.map
@@ -1,34 +0,0 @@
1
- /**
2
- * Session-start skippable nudge for coverageDebt + checkResume (#3189).
3
- *
4
- * Why / what + Strict / Hatch-aware / Later (+ Discuss / Back for #1470).
5
- * Later does not mark decided; re-nag next interactive mutation ritual.
6
- * Headless / CI / non-TTY fail-open (no block).
7
- */
8
- import { type HeadlessDetectionOptions } from "../product-signal/headless.js";
9
- /** Why block -- must appear in the nudge. */
10
- export declare const COVERAGE_CHECK_RESUME_NUDGE_WHY: string;
11
- /** What block -- bundled presets, not five micro-toggles. */
12
- export declare const COVERAGE_CHECK_RESUME_NUDGE_WHAT: string;
13
- export declare const COVERAGE_CHECK_RESUME_NUDGE_BODY: string;
14
- export interface CoverageCheckResumeNudgeEligibilityOptions extends HeadlessDetectionOptions {
15
- readonly projectRoot: string;
16
- }
17
- /**
18
- * True when an interactive mutation session-start ritual should surface the
19
- * coverage/check-resume decision nudge (#3189).
20
- */
21
- export declare function isCoverageCheckResumeNudgeEligible(options: CoverageCheckResumeNudgeEligibilityOptions): boolean;
22
- /** Format the full operator-facing nudge. */
23
- export declare function formatCoverageCheckResumeNudge(): string;
24
- /**
25
- * Emit the nudge when eligible; headless / decided callers get an empty string.
26
- * Never blocks -- session-start always continues.
27
- *
28
- * Design note (#3189): session-start is non-interactive for agent hosts (same
29
- * class as product-signal D17). Choice dispatch is via CLI verbs named in the
30
- * nudge body (`policy:coverage-check-resume-preset|later|dismiss`), not a
31
- * blocking TTY menu inside session:start.
32
- */
33
- export declare function maybeFormatCoverageCheckResumeNudge(options: CoverageCheckResumeNudgeEligibilityOptions): string;
34
- //# sourceMappingURL=coverage-check-resume-nudge.d.ts.map
@@ -1,66 +0,0 @@
1
- /**
2
- * Session-start skippable nudge for coverageDebt + checkResume (#3189).
3
- *
4
- * Why / what + Strict / Hatch-aware / Later (+ Discuss / Back for #1470).
5
- * Later does not mark decided; re-nag next interactive mutation ritual.
6
- * Headless / CI / non-TTY fail-open (no block).
7
- */
8
- import { isCoverageCheckResumeUndecided } from "../policy/coverage-check-resume-presets.js";
9
- import { policyColonInvocation } from "../policy/policy-invocation.js";
10
- import { isHeadlessSession } from "../product-signal/headless.js";
11
- /** Why block -- must appear in the nudge. */
12
- export const COVERAGE_CHECK_RESUME_NUDGE_WHY = "Why: Long checks often fail late on small gates, or barely miss coverage. " +
13
- "The project can fail closed, warn, or hatch with a tracked debt issue on THIS repo. " +
14
- "Local machines may resume a suite that already passed at the same commit; " +
15
- "CI must not trust a laptop stamp.";
16
- /** What block -- bundled presets, not five micro-toggles. */
17
- export const COVERAGE_CHECK_RESUME_NUDGE_WHAT = "What we need: one bundled project decision (not USER.md personal prefs; not npm publish; " +
18
- "not turning off required CI):\n" +
19
- " * Strict (recommended for most apps) -- coverageDebt.mode=off, checkResume.localStamp=off\n" +
20
- " * Hatch-aware -- coverageDebt.mode=hatch (autoFile=false by default), localStamp=on for DX\n" +
21
- " * Later -- skip this session; does NOT set status=decided; nag again next ritual\n" +
22
- " * Discuss -- talk through the trade-offs\n" +
23
- " * Back -- leave this prompt without choosing\n" +
24
- "Apply path (writes PROJECT-DEFINITION):\n" +
25
- " Strict -> `" +
26
- policyColonInvocation("coverage-check-resume-preset", " -- --preset strict") +
27
- "`\n" +
28
- " Hatch-aware -> `" +
29
- policyColonInvocation("coverage-check-resume-preset", " -- --preset hatch-aware") +
30
- "`\n" +
31
- " Later -> `" +
32
- policyColonInvocation("coverage-check-resume-later") +
33
- "` (no PD write)\n" +
34
- " Dismiss-with-reason -> `" +
35
- policyColonInvocation("coverage-check-resume-dismiss", ' -- --reason "…"') +
36
- "`\n" +
37
- "Stop nag only after Strict / Hatch-aware (status=decided) or dismiss-with-reason " +
38
- `(visible via \`${policyColonInvocation("show", " --field=coverageDebt")}\` / doctor).`;
39
- export const COVERAGE_CHECK_RESUME_NUDGE_BODY = `${COVERAGE_CHECK_RESUME_NUDGE_WHY}\n\n${COVERAGE_CHECK_RESUME_NUDGE_WHAT}`;
40
- /**
41
- * True when an interactive mutation session-start ritual should surface the
42
- * coverage/check-resume decision nudge (#3189).
43
- */
44
- export function isCoverageCheckResumeNudgeEligible(options) {
45
- if (isHeadlessSession(options)) {
46
- return false;
47
- }
48
- return isCoverageCheckResumeUndecided(options.projectRoot);
49
- }
50
- /** Format the full operator-facing nudge. */
51
- export function formatCoverageCheckResumeNudge() {
52
- return `[deft policy] coverageDebt + checkResume undecided:\n${COVERAGE_CHECK_RESUME_NUDGE_BODY}\n`;
53
- }
54
- /**
55
- * Emit the nudge when eligible; headless / decided callers get an empty string.
56
- * Never blocks -- session-start always continues.
57
- *
58
- * Design note (#3189): session-start is non-interactive for agent hosts (same
59
- * class as product-signal D17). Choice dispatch is via CLI verbs named in the
60
- * nudge body (`policy:coverage-check-resume-preset|later|dismiss`), not a
61
- * blocking TTY menu inside session:start.
62
- */
63
- export function maybeFormatCoverageCheckResumeNudge(options) {
64
- return isCoverageCheckResumeNudgeEligible(options) ? formatCoverageCheckResumeNudge() : "";
65
- }
66
- //# sourceMappingURL=coverage-check-resume-nudge.js.map