@deftai/directive-core 0.100.0 → 0.102.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.
- package/dist/authz/classify.js +193 -27
- package/dist/authz/decompose-apply.d.ts +14 -0
- package/dist/authz/decompose-apply.js +93 -18
- package/dist/check/cached-orchestrator.d.ts +30 -5
- package/dist/check/cached-orchestrator.js +297 -10
- package/dist/check/cli-native-gates.d.ts +43 -0
- package/dist/check/cli-native-gates.js +84 -0
- package/dist/check/gate-lists.d.ts +10 -4
- package/dist/check/gate-lists.js +19 -5
- package/dist/check/index.d.ts +4 -2
- package/dist/check/index.js +3 -1
- package/dist/check/named-cause.d.ts +45 -0
- package/dist/check/named-cause.js +131 -0
- package/dist/check/orchestrator.js +6 -1
- package/dist/doctor/checks.d.ts +5 -6
- package/dist/doctor/checks.js +13 -56
- package/dist/doctor/help.d.ts +5 -0
- package/dist/doctor/help.js +31 -0
- package/dist/doctor/index.d.ts +2 -0
- package/dist/doctor/index.js +2 -0
- package/dist/doctor/main.js +58 -0
- package/dist/doctor/session-coda.d.ts +82 -0
- package/dist/doctor/session-coda.js +151 -0
- package/dist/doctor/types.d.ts +16 -0
- package/dist/eval/later-graduation.d.ts +39 -0
- package/dist/eval/later-graduation.js +91 -0
- package/dist/eval/report.d.ts +6 -0
- package/dist/eval/report.js +27 -8
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/init-deposit/gitignore.js +2 -0
- package/dist/intake/issue-ingest.js +49 -0
- package/dist/policy/ac-pass-banking.d.ts +58 -0
- package/dist/policy/ac-pass-banking.js +150 -0
- package/dist/policy/ceremony-dial-escalation.d.ts +52 -0
- package/dist/policy/ceremony-dial-escalation.js +92 -0
- package/dist/policy/ceremony-dial.d.ts +32 -1
- package/dist/policy/ceremony-dial.js +128 -1
- package/dist/policy/check-resume.d.ts +9 -38
- package/dist/policy/check-resume.js +18 -156
- package/dist/policy/coverage-debt.d.ts +18 -37
- package/dist/policy/coverage-debt.js +38 -147
- package/dist/policy/index.d.ts +2 -1
- package/dist/policy/index.js +16 -2
- package/dist/preflight-cache/evaluate.d.ts +3 -0
- package/dist/preflight-cache/evaluate.js +3 -0
- package/dist/product-first-done-gate/acceptance.d.ts +25 -0
- package/dist/product-first-done-gate/acceptance.js +269 -0
- package/dist/product-first-done-gate/check-mode.d.ts +45 -0
- package/dist/product-first-done-gate/check-mode.js +148 -0
- package/dist/product-first-done-gate/empty-resolution.d.ts +26 -0
- package/dist/product-first-done-gate/empty-resolution.js +38 -0
- package/dist/product-first-done-gate/evaluate.d.ts +76 -0
- package/dist/product-first-done-gate/evaluate.js +411 -0
- package/dist/product-first-done-gate/index.d.ts +12 -0
- package/dist/product-first-done-gate/index.js +12 -0
- package/dist/product-first-done-gate/types.d.ts +67 -0
- package/dist/product-first-done-gate/types.js +54 -0
- package/dist/run-summary/emit.d.ts +66 -0
- package/dist/run-summary/emit.js +217 -0
- package/dist/run-summary/index.d.ts +5 -0
- package/dist/run-summary/index.js +5 -0
- package/dist/run-summary/path.d.ts +25 -0
- package/dist/run-summary/path.js +78 -0
- package/dist/run-summary/share.d.ts +25 -0
- package/dist/run-summary/share.js +106 -0
- package/dist/run-summary/types.d.ts +134 -0
- package/dist/run-summary/types.js +28 -0
- package/dist/scope/acceptance-activate-gate.d.ts +23 -0
- package/dist/scope/acceptance-activate-gate.js +70 -0
- package/dist/scope/acceptance-evidence.d.ts +34 -0
- package/dist/scope/acceptance-evidence.js +84 -10
- package/dist/scope/decompose.d.ts +5 -0
- package/dist/scope/decompose.js +11 -2
- package/dist/scope/index.d.ts +1 -0
- package/dist/scope/index.js +1 -0
- package/dist/scope/transition.js +5 -0
- package/dist/session/ac-pass-banking.d.ts +221 -0
- package/dist/session/ac-pass-banking.js +761 -0
- package/dist/session/deposit-sha.d.ts +49 -0
- package/dist/session/deposit-sha.js +121 -0
- package/dist/session/effort-budget.d.ts +6 -0
- package/dist/session/effort-budget.js +21 -3
- package/dist/session/index.d.ts +5 -1
- package/dist/session/index.js +5 -1
- package/dist/session/orientation-compression.d.ts +127 -0
- package/dist/session/orientation-compression.js +435 -0
- package/dist/session/orientation-state.d.ts +29 -0
- package/dist/session/orientation-state.js +85 -0
- package/dist/session/session-start.d.ts +31 -0
- package/dist/session/session-start.js +219 -22
- package/dist/session/toolchain-preflight.d.ts +79 -0
- package/dist/session/toolchain-preflight.js +211 -0
- package/dist/triage/bootstrap/gitignore.d.ts +1 -1
- package/dist/triage/bootstrap/gitignore.js +8 -2
- package/dist/triage/bootstrap/index.js +15 -3
- package/dist/triage/classify/index.d.ts +1 -0
- package/dist/triage/classify/index.js +2 -0
- package/dist/triage/classify/label-mirror.js +16 -0
- package/dist/triage/classify/mirror-discovery-tip.d.ts +95 -0
- package/dist/triage/classify/mirror-discovery-tip.js +234 -0
- package/dist/triage/reconcile/reconcile.js +28 -6
- package/dist/triage/summary/index.js +12 -4
- package/dist/triage/welcome/default-mode.js +16 -0
- package/dist/ts-check-lane/run-lane.js +21 -4
- package/dist/vbrief-validate/conformance.js +7 -0
- package/dist/verify-ac/clauses.d.ts +51 -0
- package/dist/verify-ac/clauses.js +490 -0
- package/dist/verify-ac/evaluate.d.ts +55 -0
- package/dist/verify-ac/evaluate.js +145 -0
- package/dist/verify-ac/flag.d.ts +35 -0
- package/dist/verify-ac/flag.js +104 -0
- package/dist/verify-ac/index.d.ts +10 -0
- package/dist/verify-ac/index.js +10 -0
- package/dist/vitest-runner/coverage-debt-teardown.js +16 -4
- package/package.json +15 -3
- package/dist/policy/coverage-check-resume-presets.d.ts +0 -46
- package/dist/policy/coverage-check-resume-presets.js +0 -228
- package/dist/session/coverage-check-resume-nudge.d.ts +0 -34
- package/dist/session/coverage-check-resume-nudge.js +0 -66
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orientation compression Now path (#3286 / dual-path #2899).
|
|
3
|
+
*
|
|
4
|
+
* Composes doctor + toolchain preflight into session:start as inline sections
|
|
5
|
+
* with per-section status lines; offers deposit-sha fast-paths for
|
|
6
|
+
* agents:refresh and verify:cache-fresh; formats compact (opt-in) vs verbose
|
|
7
|
+
* (default). Does NOT implement unified `deft orient` (Later remains open).
|
|
8
|
+
*/
|
|
9
|
+
import { isFrameworkRepoRoot } from "../check/context.js";
|
|
10
|
+
import { decideThrottle, readState as readDoctorState, renderDoctorStatusLine, } from "../doctor/doctor-state.js";
|
|
11
|
+
import { cmdDoctor } from "../doctor/main.js";
|
|
12
|
+
import { applyAgentsRefresh } from "../platform/agents-md.js";
|
|
13
|
+
import { evaluate as evaluateCacheFresh, } from "../preflight-cache/evaluate.js";
|
|
14
|
+
import { computeDepositSha, DEPOSIT_SHA_MATCH_NOOP, formatDepositShaMatchLine, } from "./deposit-sha.js";
|
|
15
|
+
import { readOrientationState, surfaceRecord, writeOrientationState, } from "./orientation-state.js";
|
|
16
|
+
import { runToolchainPreflight, toolchainPreflightToDict, } from "./toolchain-preflight.js";
|
|
17
|
+
/** Env opt-in for compact orientation output (#3286). Verbose remains default. */
|
|
18
|
+
export const ENV_SESSION_COMPACT = "DEFT_SESSION_COMPACT";
|
|
19
|
+
/** Dual-path Later graduation status — Now ships without closing Later (#2899). */
|
|
20
|
+
export const ORIENTATION_LATER_STATUS = "open";
|
|
21
|
+
export const ORIENTATION_LATER_COMMAND = "deft orient";
|
|
22
|
+
export const ORIENTATION_GRADUATION_TRIGGER = "post-#3282 run-summary telemetry shows ritual+gate share >= 25% of tool calls " +
|
|
23
|
+
"on a benchmark-suite run AFTER Now ships (starting threshold, tunable)";
|
|
24
|
+
function elapsedMs(started) {
|
|
25
|
+
return Math.max(0, Math.round(performance.now() - started));
|
|
26
|
+
}
|
|
27
|
+
function truthyEnv(raw) {
|
|
28
|
+
return new Set(["1", "true", "yes", "on"]).has((raw ?? "").trim().toLowerCase());
|
|
29
|
+
}
|
|
30
|
+
/** Resolve compact flag: explicit option wins, else DEFT_SESSION_COMPACT. */
|
|
31
|
+
export function resolveSessionCompact(options = {}) {
|
|
32
|
+
if (options.compact === true)
|
|
33
|
+
return true;
|
|
34
|
+
if (options.compact === false)
|
|
35
|
+
return false;
|
|
36
|
+
const env = options.env ?? process.env;
|
|
37
|
+
return truthyEnv(env[ENV_SESSION_COMPACT]);
|
|
38
|
+
}
|
|
39
|
+
function statusLine(name, status) {
|
|
40
|
+
return `[deft orientation] ${name}: ${status}`;
|
|
41
|
+
}
|
|
42
|
+
/** Compact machine lines (one per section). Verbose default keeps prose. */
|
|
43
|
+
export function formatOrientationCompactLines(sections) {
|
|
44
|
+
return sections.map((s) => {
|
|
45
|
+
const tag = s.shaMatch ? "sha_match" : s.status;
|
|
46
|
+
return `${s.name}=${tag}`;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
export function formatOrientationVerboseLines(sections) {
|
|
50
|
+
const out = [];
|
|
51
|
+
for (const section of sections) {
|
|
52
|
+
out.push(statusLine(section.name, section.status));
|
|
53
|
+
for (const line of section.lines) {
|
|
54
|
+
// Avoid duplicating the status header when the section already emitted it.
|
|
55
|
+
if (line === statusLine(section.name, section.status))
|
|
56
|
+
continue;
|
|
57
|
+
out.push(line);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Doctor orientation section — throttle status when clean/recent; otherwise
|
|
64
|
+
* run doctor and surface a per-section status line (#3286 compose).
|
|
65
|
+
*/
|
|
66
|
+
export function runDoctorOrientationSection(projectRoot, options = {}) {
|
|
67
|
+
const started = performance.now();
|
|
68
|
+
const now = options.now ?? new Date();
|
|
69
|
+
try {
|
|
70
|
+
const state = readDoctorState(projectRoot);
|
|
71
|
+
const decision = decideThrottle(state, now);
|
|
72
|
+
if (decision.skip) {
|
|
73
|
+
const dirty = decision.dirty;
|
|
74
|
+
const status = dirty ? "dirty" : "ok";
|
|
75
|
+
const line = renderDoctorStatusLine(decision, now);
|
|
76
|
+
return {
|
|
77
|
+
name: "doctor",
|
|
78
|
+
status,
|
|
79
|
+
ok: !dirty,
|
|
80
|
+
exitCode: dirty ? 1 : 0,
|
|
81
|
+
lines: [line],
|
|
82
|
+
shaMatch: false,
|
|
83
|
+
durationMs: elapsedMs(started),
|
|
84
|
+
detail: { throttle_skipped: true, dirty },
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const runner = options.doctorRunner ?? cmdDoctor;
|
|
88
|
+
// Capture stdout/stderr from doctor JSON mode for a terse status.
|
|
89
|
+
const captured = [];
|
|
90
|
+
const prevOut = process.stdout.write.bind(process.stdout);
|
|
91
|
+
const prevErr = process.stderr.write.bind(process.stderr);
|
|
92
|
+
const capture = (chunk) => {
|
|
93
|
+
captured.push(String(chunk));
|
|
94
|
+
return true;
|
|
95
|
+
};
|
|
96
|
+
process.stdout.write = capture;
|
|
97
|
+
process.stderr.write = capture;
|
|
98
|
+
let code = 0;
|
|
99
|
+
try {
|
|
100
|
+
code = runner(["--project-root", projectRoot, "--json"], options.seams);
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
process.stdout.write = prevOut;
|
|
104
|
+
process.stderr.write = prevErr;
|
|
105
|
+
}
|
|
106
|
+
const status = code === 0 ? "ok" : code === 1 ? "dirty" : "error";
|
|
107
|
+
const summary = code === 0 ? "[deft doctor] status: ok" : `[deft doctor] status: ${status} (exit ${code})`;
|
|
108
|
+
return {
|
|
109
|
+
name: "doctor",
|
|
110
|
+
status,
|
|
111
|
+
ok: code === 0,
|
|
112
|
+
exitCode: code,
|
|
113
|
+
lines: [summary],
|
|
114
|
+
shaMatch: false,
|
|
115
|
+
durationMs: elapsedMs(started),
|
|
116
|
+
detail: { throttle_skipped: false, captured_len: captured.join("").length },
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
catch (exc) {
|
|
120
|
+
// Session:start continues, but do not persist as a successful gated doctor
|
|
121
|
+
// step (Greptile #3286) — next verify:session-ritual must re-run doctor.
|
|
122
|
+
return {
|
|
123
|
+
name: "doctor",
|
|
124
|
+
status: "error",
|
|
125
|
+
ok: false,
|
|
126
|
+
exitCode: 2,
|
|
127
|
+
lines: [`[deft doctor] status: error (session continues): ${String(exc)}`],
|
|
128
|
+
shaMatch: false,
|
|
129
|
+
durationMs: elapsedMs(started),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export function runPreflightOrientationSection(projectRoot, options = {}) {
|
|
134
|
+
const started = performance.now();
|
|
135
|
+
if (options.result === null) {
|
|
136
|
+
return {
|
|
137
|
+
section: {
|
|
138
|
+
name: "preflight",
|
|
139
|
+
status: "skipped",
|
|
140
|
+
ok: true,
|
|
141
|
+
exitCode: 0,
|
|
142
|
+
lines: ["[deft preflight] toolchain status: skipped"],
|
|
143
|
+
shaMatch: false,
|
|
144
|
+
durationMs: 0,
|
|
145
|
+
},
|
|
146
|
+
preflight: null,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
const preflight = options.result ??
|
|
151
|
+
runToolchainPreflight({
|
|
152
|
+
projectRoot,
|
|
153
|
+
frameworkRoot: options.frameworkRoot ?? projectRoot,
|
|
154
|
+
...options.preflightOptions,
|
|
155
|
+
});
|
|
156
|
+
const status = preflight.ok
|
|
157
|
+
? "ok"
|
|
158
|
+
: preflight.degraded
|
|
159
|
+
? "degraded"
|
|
160
|
+
: "error";
|
|
161
|
+
return {
|
|
162
|
+
section: {
|
|
163
|
+
name: "preflight",
|
|
164
|
+
status,
|
|
165
|
+
ok: preflight.ok || preflight.degraded,
|
|
166
|
+
exitCode: preflight.ok ? 0 : 1,
|
|
167
|
+
lines: [...preflight.lines],
|
|
168
|
+
shaMatch: false,
|
|
169
|
+
durationMs: elapsedMs(started),
|
|
170
|
+
detail: toolchainPreflightToDict(preflight),
|
|
171
|
+
},
|
|
172
|
+
preflight,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
catch (exc) {
|
|
176
|
+
return {
|
|
177
|
+
section: {
|
|
178
|
+
name: "preflight",
|
|
179
|
+
status: "error",
|
|
180
|
+
ok: false,
|
|
181
|
+
exitCode: 2,
|
|
182
|
+
lines: [`[deft preflight] toolchain status: error (session continues): ${String(exc)}`],
|
|
183
|
+
shaMatch: false,
|
|
184
|
+
durationMs: elapsedMs(started),
|
|
185
|
+
},
|
|
186
|
+
preflight: null,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* agents:refresh orientation section (#3286).
|
|
192
|
+
* Always plans against live AGENTS.md so local managed-section edits are
|
|
193
|
+
* detected (deposit fingerprint alone is insufficient). Content-current →
|
|
194
|
+
* one-line sha-match phrasing; deposit-sha is recorded for orientation telemetry.
|
|
195
|
+
*/
|
|
196
|
+
export function runAgentsRefreshOrientationSection(projectRoot, options) {
|
|
197
|
+
const started = performance.now();
|
|
198
|
+
void options.prior;
|
|
199
|
+
try {
|
|
200
|
+
const apply = options.apply ?? applyAgentsRefresh;
|
|
201
|
+
const result = apply(projectRoot, {});
|
|
202
|
+
if (result.state === "current") {
|
|
203
|
+
const line = formatDepositShaMatchLine("agents:refresh");
|
|
204
|
+
return {
|
|
205
|
+
name: "agents_refresh",
|
|
206
|
+
status: "sha_match",
|
|
207
|
+
ok: true,
|
|
208
|
+
exitCode: 0,
|
|
209
|
+
lines: [line],
|
|
210
|
+
shaMatch: true,
|
|
211
|
+
depositSha: options.depositSha,
|
|
212
|
+
durationMs: elapsedMs(started),
|
|
213
|
+
detail: { state: result.state, wrote: result.wrote },
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
if (result.state === "template-missing" ||
|
|
217
|
+
result.state === "template-malformed" ||
|
|
218
|
+
result.state === "unreadable") {
|
|
219
|
+
return {
|
|
220
|
+
name: "agents_refresh",
|
|
221
|
+
status: "error",
|
|
222
|
+
ok: false,
|
|
223
|
+
exitCode: 2,
|
|
224
|
+
lines: [`[deft agents:refresh] failed: ${result.state}`],
|
|
225
|
+
shaMatch: false,
|
|
226
|
+
depositSha: options.depositSha,
|
|
227
|
+
durationMs: elapsedMs(started),
|
|
228
|
+
detail: { state: result.state },
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
const wrote = result.wrote;
|
|
232
|
+
const msg = wrote
|
|
233
|
+
? `[deft agents:refresh] updated (state=${result.state})`
|
|
234
|
+
: `[deft agents:refresh] state=${result.state}`;
|
|
235
|
+
return {
|
|
236
|
+
name: "agents_refresh",
|
|
237
|
+
status: "ok",
|
|
238
|
+
ok: true,
|
|
239
|
+
exitCode: 0,
|
|
240
|
+
lines: [msg],
|
|
241
|
+
shaMatch: false,
|
|
242
|
+
depositSha: options.depositSha,
|
|
243
|
+
durationMs: elapsedMs(started),
|
|
244
|
+
detail: { state: result.state, wrote },
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
catch (exc) {
|
|
248
|
+
// Fail-open for session:start composition, but do NOT persist as ok —
|
|
249
|
+
// next session must retry (Greptile #3286 P1).
|
|
250
|
+
return {
|
|
251
|
+
name: "agents_refresh",
|
|
252
|
+
status: "error",
|
|
253
|
+
ok: false,
|
|
254
|
+
exitCode: 2,
|
|
255
|
+
lines: [`[deft agents:refresh] error (session continues): ${String(exc)}`],
|
|
256
|
+
shaMatch: false,
|
|
257
|
+
depositSha: options.depositSha,
|
|
258
|
+
durationMs: elapsedMs(started),
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* verify:cache-fresh orientation section (#3286).
|
|
264
|
+
* Always runs the live evaluate (age + drift). Deposit fingerprint is recorded
|
|
265
|
+
* for orientation telemetry only — it must not suppress triage-cache freshness.
|
|
266
|
+
* When evaluate is already clean, surface a one-line sha-match-style no-op only
|
|
267
|
+
* if the message is the canonical deposit phrase (not used for shortcuts).
|
|
268
|
+
*/
|
|
269
|
+
export function runCacheFreshOrientationSection(projectRoot, options) {
|
|
270
|
+
const started = performance.now();
|
|
271
|
+
void options.prior;
|
|
272
|
+
void options.now;
|
|
273
|
+
try {
|
|
274
|
+
const evaluate = options.evaluateFn ?? evaluateCacheFresh;
|
|
275
|
+
const consumerDeposit = !isFrameworkRepoRoot(projectRoot);
|
|
276
|
+
// Consumer deposits often have no triage cache. Treat that as a named
|
|
277
|
+
// bootstrap cause (dirty), never a generic orientation `error` (#3335).
|
|
278
|
+
// Framework source still evaluates live; missing cache stays non-green
|
|
279
|
+
// (#3286) so gated verify re-runs cache_fresh.
|
|
280
|
+
const result = evaluate(projectRoot, {
|
|
281
|
+
allowMissingBootstrap: false,
|
|
282
|
+
autoPopulateEmpty: false,
|
|
283
|
+
...options.evaluateOptions,
|
|
284
|
+
});
|
|
285
|
+
const ok = result.code === 0;
|
|
286
|
+
const missingCache = result.code === 2 && /not found|bootstrap/i.test(result.message);
|
|
287
|
+
const namedCause = missingCache
|
|
288
|
+
? consumerDeposit
|
|
289
|
+
? `[deft cache-fresh] triage cache not populated (consumer deposit) — not a toolchain failure. Recovery: run \`deft triage:bootstrap\` if you need the queue.`
|
|
290
|
+
: result.message
|
|
291
|
+
: result.message;
|
|
292
|
+
// Tag as sha_match only when message already uses the canonical phrase
|
|
293
|
+
// (e.g. tests inject it) — never invent a shortcut past evaluate.
|
|
294
|
+
const shaMatch = ok && result.message.includes(DEPOSIT_SHA_MATCH_NOOP);
|
|
295
|
+
const status = shaMatch
|
|
296
|
+
? "sha_match"
|
|
297
|
+
: ok
|
|
298
|
+
? "ok"
|
|
299
|
+
: missingCache
|
|
300
|
+
? "dirty"
|
|
301
|
+
: result.code === 2
|
|
302
|
+
? "error"
|
|
303
|
+
: "dirty";
|
|
304
|
+
return {
|
|
305
|
+
name: "cache_fresh",
|
|
306
|
+
status,
|
|
307
|
+
ok,
|
|
308
|
+
exitCode: result.code,
|
|
309
|
+
lines: [namedCause],
|
|
310
|
+
shaMatch,
|
|
311
|
+
depositSha: options.depositSha,
|
|
312
|
+
durationMs: elapsedMs(started),
|
|
313
|
+
detail: { code: result.code, missing_cache: missingCache },
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
catch (exc) {
|
|
317
|
+
return {
|
|
318
|
+
name: "cache_fresh",
|
|
319
|
+
status: "error",
|
|
320
|
+
ok: false,
|
|
321
|
+
exitCode: 2,
|
|
322
|
+
lines: [`[deft cache-fresh] error (session continues): ${String(exc)}`],
|
|
323
|
+
shaMatch: false,
|
|
324
|
+
depositSha: options.depositSha,
|
|
325
|
+
durationMs: elapsedMs(started),
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
function toSurface(section, now) {
|
|
330
|
+
return surfaceRecord(section.ok, section.exitCode, now, section.lines[0]);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Run the composed orientation sections for a mutation cold session:start.
|
|
334
|
+
*/
|
|
335
|
+
export function runOrientationCompression(options) {
|
|
336
|
+
const projectRoot = options.projectRoot;
|
|
337
|
+
const now = options.now ?? new Date();
|
|
338
|
+
const compact = resolveSessionCompact(options);
|
|
339
|
+
const depositSha = computeDepositSha({
|
|
340
|
+
projectRoot,
|
|
341
|
+
frameworkRoot: options.frameworkRoot ?? projectRoot,
|
|
342
|
+
...options.depositShaOptions,
|
|
343
|
+
});
|
|
344
|
+
const prior = readOrientationState(projectRoot);
|
|
345
|
+
const sections = [];
|
|
346
|
+
let preflightResult = null;
|
|
347
|
+
if (options.includeDoctor !== false) {
|
|
348
|
+
const doctor = options.doctorSection !== undefined
|
|
349
|
+
? options.doctorSection
|
|
350
|
+
: runDoctorOrientationSection(projectRoot, {
|
|
351
|
+
now,
|
|
352
|
+
seams: options.doctorSeams,
|
|
353
|
+
});
|
|
354
|
+
if (doctor !== null)
|
|
355
|
+
sections.push(doctor);
|
|
356
|
+
}
|
|
357
|
+
if (options.includePreflight !== false) {
|
|
358
|
+
const { section, preflight } = runPreflightOrientationSection(projectRoot, {
|
|
359
|
+
frameworkRoot: options.frameworkRoot,
|
|
360
|
+
result: options.toolchainPreflight,
|
|
361
|
+
preflightOptions: options.toolchainPreflightOptions,
|
|
362
|
+
});
|
|
363
|
+
preflightResult = preflight;
|
|
364
|
+
if (section !== null)
|
|
365
|
+
sections.push(section);
|
|
366
|
+
}
|
|
367
|
+
if (options.includeAgentsRefresh !== false) {
|
|
368
|
+
const agents = options.agentsRefreshSection !== undefined
|
|
369
|
+
? options.agentsRefreshSection
|
|
370
|
+
: runAgentsRefreshOrientationSection(projectRoot, {
|
|
371
|
+
depositSha,
|
|
372
|
+
prior,
|
|
373
|
+
now,
|
|
374
|
+
});
|
|
375
|
+
if (agents !== null)
|
|
376
|
+
sections.push(agents);
|
|
377
|
+
}
|
|
378
|
+
if (options.includeCacheFresh !== false) {
|
|
379
|
+
const cache = options.cacheFreshSection !== undefined
|
|
380
|
+
? options.cacheFreshSection
|
|
381
|
+
: runCacheFreshOrientationSection(projectRoot, {
|
|
382
|
+
depositSha,
|
|
383
|
+
prior,
|
|
384
|
+
now,
|
|
385
|
+
evaluateOptions: options.cacheFreshOptions,
|
|
386
|
+
});
|
|
387
|
+
if (cache !== null)
|
|
388
|
+
sections.push(cache);
|
|
389
|
+
}
|
|
390
|
+
const lines = compact
|
|
391
|
+
? formatOrientationCompactLines(sections)
|
|
392
|
+
: formatOrientationVerboseLines(sections);
|
|
393
|
+
const byName = (n) => sections.find((s) => s.name === n);
|
|
394
|
+
const state = {
|
|
395
|
+
schema_version: 1,
|
|
396
|
+
deposit_sha: depositSha,
|
|
397
|
+
updated_at: now.toISOString().replace(/\.\d{3}Z$/, "Z"),
|
|
398
|
+
...(byName("agents_refresh")
|
|
399
|
+
? { agents_refresh: toSurface(byName("agents_refresh"), now) }
|
|
400
|
+
: {}),
|
|
401
|
+
...(byName("cache_fresh")
|
|
402
|
+
? { cache_fresh: toSurface(byName("cache_fresh"), now) }
|
|
403
|
+
: {}),
|
|
404
|
+
...(byName("doctor")
|
|
405
|
+
? { doctor: toSurface(byName("doctor"), now) }
|
|
406
|
+
: {}),
|
|
407
|
+
...(byName("preflight")
|
|
408
|
+
? { preflight: toSurface(byName("preflight"), now) }
|
|
409
|
+
: {}),
|
|
410
|
+
};
|
|
411
|
+
if (options.persistState !== false) {
|
|
412
|
+
try {
|
|
413
|
+
writeOrientationState(projectRoot, state);
|
|
414
|
+
}
|
|
415
|
+
catch {
|
|
416
|
+
// fail-open
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
depositSha,
|
|
421
|
+
compact,
|
|
422
|
+
sections,
|
|
423
|
+
lines,
|
|
424
|
+
orientationCallCount: sections.length,
|
|
425
|
+
later: {
|
|
426
|
+
status: ORIENTATION_LATER_STATUS,
|
|
427
|
+
command: ORIENTATION_LATER_COMMAND,
|
|
428
|
+
trigger: ORIENTATION_GRADUATION_TRIGGER,
|
|
429
|
+
},
|
|
430
|
+
preflight: preflightResult,
|
|
431
|
+
state,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
export { computeDepositSha, DEPOSIT_SHA_MATCH_NOOP, depositShaMatches, formatDepositShaMatchLine, } from "./deposit-sha.js";
|
|
435
|
+
//# sourceMappingURL=orientation-compression.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persisted orientation deposit fingerprint (#3286).
|
|
3
|
+
*
|
|
4
|
+
* Enables agents:refresh / verify:cache-fresh one-line sha-match no-ops on
|
|
5
|
+
* repeat sessions when payload + templates + engine are unchanged.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ORIENTATION_STATE_REL: string;
|
|
8
|
+
export declare const ORIENTATION_STATE_SCHEMA: 1;
|
|
9
|
+
export interface OrientationSurfaceRecord {
|
|
10
|
+
readonly ok: boolean;
|
|
11
|
+
readonly ts: string;
|
|
12
|
+
readonly exit_code: number;
|
|
13
|
+
readonly message?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface OrientationState {
|
|
16
|
+
readonly schema_version: typeof ORIENTATION_STATE_SCHEMA;
|
|
17
|
+
readonly deposit_sha: string;
|
|
18
|
+
readonly updated_at: string;
|
|
19
|
+
readonly agents_refresh?: OrientationSurfaceRecord;
|
|
20
|
+
readonly cache_fresh?: OrientationSurfaceRecord;
|
|
21
|
+
readonly doctor?: OrientationSurfaceRecord;
|
|
22
|
+
readonly preflight?: OrientationSurfaceRecord;
|
|
23
|
+
}
|
|
24
|
+
export declare function orientationStatePath(projectRoot: string): string;
|
|
25
|
+
export declare function parseOrientationState(raw: unknown): OrientationState | null;
|
|
26
|
+
export declare function readOrientationState(projectRoot: string): OrientationState | null;
|
|
27
|
+
export declare function writeOrientationState(projectRoot: string, state: OrientationState): string;
|
|
28
|
+
export declare function surfaceRecord(ok: boolean, exitCode: number, now: Date, message?: string): OrientationSurfaceRecord;
|
|
29
|
+
//# sourceMappingURL=orientation-state.d.ts.map
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persisted orientation deposit fingerprint (#3286).
|
|
3
|
+
*
|
|
4
|
+
* Enables agents:refresh / verify:cache-fresh one-line sha-match no-ops on
|
|
5
|
+
* repeat sessions when payload + templates + engine are unchanged.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
8
|
+
import { dirname, join, resolve } from "node:path";
|
|
9
|
+
import { containedWrite } from "../fs/contained-write.js";
|
|
10
|
+
export const ORIENTATION_STATE_REL = join(".deft", "orientation-state.json");
|
|
11
|
+
export const ORIENTATION_STATE_SCHEMA = 1;
|
|
12
|
+
export function orientationStatePath(projectRoot) {
|
|
13
|
+
return join(resolve(projectRoot), ORIENTATION_STATE_REL);
|
|
14
|
+
}
|
|
15
|
+
function parseRecord(raw) {
|
|
16
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
17
|
+
return undefined;
|
|
18
|
+
const rec = raw;
|
|
19
|
+
if (typeof rec.ok !== "boolean")
|
|
20
|
+
return undefined;
|
|
21
|
+
if (typeof rec.ts !== "string" || rec.ts.trim().length === 0)
|
|
22
|
+
return undefined;
|
|
23
|
+
const exit = typeof rec.exit_code === "number" ? rec.exit_code : rec.ok ? 0 : 1;
|
|
24
|
+
return {
|
|
25
|
+
ok: rec.ok,
|
|
26
|
+
ts: rec.ts,
|
|
27
|
+
exit_code: exit,
|
|
28
|
+
message: typeof rec.message === "string" ? rec.message : undefined,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function parseOrientationState(raw) {
|
|
32
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
33
|
+
return null;
|
|
34
|
+
const rec = raw;
|
|
35
|
+
if (typeof rec.deposit_sha !== "string" || rec.deposit_sha.trim().length === 0)
|
|
36
|
+
return null;
|
|
37
|
+
if (typeof rec.updated_at !== "string" || rec.updated_at.trim().length === 0)
|
|
38
|
+
return null;
|
|
39
|
+
const schema = typeof rec.schema_version === "number" ? rec.schema_version : ORIENTATION_STATE_SCHEMA;
|
|
40
|
+
if (schema !== ORIENTATION_STATE_SCHEMA)
|
|
41
|
+
return null;
|
|
42
|
+
return {
|
|
43
|
+
schema_version: ORIENTATION_STATE_SCHEMA,
|
|
44
|
+
deposit_sha: rec.deposit_sha.trim(),
|
|
45
|
+
updated_at: rec.updated_at.trim(),
|
|
46
|
+
agents_refresh: parseRecord(rec.agents_refresh),
|
|
47
|
+
cache_fresh: parseRecord(rec.cache_fresh),
|
|
48
|
+
doctor: parseRecord(rec.doctor),
|
|
49
|
+
preflight: parseRecord(rec.preflight),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export function readOrientationState(projectRoot) {
|
|
53
|
+
const path = orientationStatePath(projectRoot);
|
|
54
|
+
if (!existsSync(path))
|
|
55
|
+
return null;
|
|
56
|
+
try {
|
|
57
|
+
const text = readFileSync(path, "utf8");
|
|
58
|
+
return parseOrientationState(JSON.parse(text));
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export function writeOrientationState(projectRoot, state) {
|
|
65
|
+
const path = orientationStatePath(projectRoot);
|
|
66
|
+
const parent = dirname(path);
|
|
67
|
+
mkdirSync(parent, { recursive: true });
|
|
68
|
+
const body = `${JSON.stringify(state, null, 2)}\n`;
|
|
69
|
+
containedWrite({
|
|
70
|
+
root: resolve(projectRoot),
|
|
71
|
+
target: path,
|
|
72
|
+
data: body,
|
|
73
|
+
mode: "replace",
|
|
74
|
+
});
|
|
75
|
+
return path;
|
|
76
|
+
}
|
|
77
|
+
export function surfaceRecord(ok, exitCode, now, message) {
|
|
78
|
+
return {
|
|
79
|
+
ok,
|
|
80
|
+
ts: now.toISOString().replace(/\.\d{3}Z$/, "Z"),
|
|
81
|
+
exit_code: exitCode,
|
|
82
|
+
...(message !== undefined ? { message } : {}),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=orientation-state.js.map
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { type HostContentSurfaceSeams } from "../platform/host-content-surface.js";
|
|
2
2
|
import { type EnvironmentContext } from "../platform/shell-context.js";
|
|
3
3
|
import { type CeremonyDialInputs, type CeremonyDialSelection, type ProvisionalCeremonyEstimateHints } from "../policy/ceremony-dial.js";
|
|
4
|
+
import { type CeremonyStartTierProvenance } from "../policy/ceremony-dial-escalation.js";
|
|
4
5
|
import { type ProbeScmReadinessOptions, type ScmReadinessReport } from "../scm/readiness.js";
|
|
5
6
|
import { type ResolveUserMdResult } from "../user-config/resolve-user-md.js";
|
|
6
7
|
import { type DetectHardEffortBudgetInput } from "./effort-budget.js";
|
|
7
8
|
import type { GitRunner } from "./git.js";
|
|
9
|
+
import { type OrientationBundle, type RunOrientationOptions } from "./orientation-compression.js";
|
|
8
10
|
import { type ReleaseAvailabilityProbeOptions } from "./release-availability.js";
|
|
9
11
|
import { type RitualState, ritualStatePath } from "./ritual-sentinel.js";
|
|
12
|
+
import { type ToolchainPreflightOptions, type ToolchainPreflightResult } from "./toolchain-preflight.js";
|
|
10
13
|
export declare const SESSION_POSTURES: readonly ["read-only", "mutation"];
|
|
11
14
|
export type SessionPosture = (typeof SESSION_POSTURES)[number];
|
|
12
15
|
export declare const READ_ONLY_POSTURE: SessionPosture;
|
|
@@ -123,6 +126,34 @@ export interface SessionStartOptions {
|
|
|
123
126
|
* loads plan.policy.ceremonyDial and applies inputs (after provisional fill).
|
|
124
127
|
*/
|
|
125
128
|
readonly ceremonyDial?: CeremonyDialSelection;
|
|
129
|
+
/**
|
|
130
|
+
* #3319: start-tier provenance hint. CLI `--ceremony-depth` / harness pin
|
|
131
|
+
* should pass `external-pin`. Policy override is inferred as `operator`.
|
|
132
|
+
*/
|
|
133
|
+
readonly ceremonyDialStartTierProvenance?: CeremonyStartTierProvenance;
|
|
134
|
+
/**
|
|
135
|
+
* #3282: done-gate toolchain preflight seams (tests inject result or probe).
|
|
136
|
+
* When omitted, runs live preflight after verify_tools on cold path.
|
|
137
|
+
* #3286: preflight is composed into orientation sections with doctor +
|
|
138
|
+
* deposit-sha fast-paths for agents:refresh / cache-fresh.
|
|
139
|
+
*/
|
|
140
|
+
readonly toolchainPreflight?: ToolchainPreflightResult | null;
|
|
141
|
+
readonly toolchainPreflightOptions?: ToolchainPreflightOptions;
|
|
142
|
+
/** #3282: disable run-summary emission (tests). */
|
|
143
|
+
readonly emitRunSummary?: boolean;
|
|
144
|
+
/** #3282: framework root for CLI dist probe (defaults to projectRoot). */
|
|
145
|
+
readonly frameworkRoot?: string;
|
|
146
|
+
/**
|
|
147
|
+
* #3286: compact orientation output (terse machine lines). Default verbose.
|
|
148
|
+
* CLI: `--compact`; env: `DEFT_SESSION_COMPACT=1`.
|
|
149
|
+
*/
|
|
150
|
+
readonly compact?: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* #3286: orientation compression seams (tests inject full bundle or partial
|
|
153
|
+
* section overrides). When `orientation === null`, skip composition entirely.
|
|
154
|
+
*/
|
|
155
|
+
readonly orientation?: OrientationBundle | null;
|
|
156
|
+
readonly orientationOptions?: Partial<RunOrientationOptions>;
|
|
126
157
|
}
|
|
127
158
|
/** Format preferred `session:start` recovery command for cold vs re-arm (#2992). */
|
|
128
159
|
export declare function formatSessionStartRecoveryCommand(tier?: SessionCeremonyTier): string;
|