@deftai/directive-core 0.99.0 → 0.100.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/actions.d.ts +6 -0
- package/dist/authz/actions.js +3 -0
- package/dist/authz/classify.js +157 -23
- package/dist/authz/decompose-apply.d.ts +67 -0
- package/dist/authz/decompose-apply.js +302 -0
- package/dist/authz/index.d.ts +3 -1
- package/dist/authz/index.js +3 -1
- package/dist/authz/store.d.ts +53 -0
- package/dist/authz/store.js +219 -1
- package/dist/authz/types.d.ts +19 -2
- package/dist/authz/types.js +5 -1
- package/dist/doctor/checks.d.ts +44 -0
- package/dist/doctor/checks.js +428 -2
- package/dist/doctor/main.d.ts +6 -7
- package/dist/doctor/main.js +72 -79
- package/dist/doctor/which.d.ts +20 -1
- package/dist/doctor/which.js +67 -1
- package/dist/finish-loop/pr-finish-loop.d.ts +13 -2
- package/dist/finish-loop/pr-finish-loop.js +116 -5
- package/dist/finish-loop/types.d.ts +1 -1
- package/dist/hooks/dispatcher.d.ts +9 -5
- package/dist/hooks/dispatcher.js +23 -15
- package/dist/hooks/readonly.d.ts +6 -3
- package/dist/hooks/readonly.js +44 -25
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/init-deposit/agent-hooks.d.ts +20 -0
- package/dist/init-deposit/agent-hooks.js +51 -31
- package/dist/intake/issue-ingest.js +29 -0
- package/dist/lifecycle/completed-consistency.d.ts +60 -0
- package/dist/lifecycle/completed-consistency.js +443 -0
- package/dist/lifecycle/completed-tracked-on-delivery.d.ts +47 -0
- package/dist/lifecycle/completed-tracked-on-delivery.js +415 -0
- package/dist/lifecycle/index.d.ts +2 -0
- package/dist/lifecycle/index.js +2 -0
- package/dist/literal-acceptance/capture.d.ts +52 -0
- package/dist/literal-acceptance/capture.js +658 -0
- package/dist/literal-acceptance/evaluate.d.ts +47 -0
- package/dist/literal-acceptance/evaluate.js +193 -0
- package/dist/literal-acceptance/index.d.ts +12 -0
- package/dist/literal-acceptance/index.js +12 -0
- package/dist/literal-acceptance/run.d.ts +38 -0
- package/dist/literal-acceptance/run.js +216 -0
- package/dist/literal-acceptance/safety.d.ts +24 -0
- package/dist/literal-acceptance/safety.js +251 -0
- package/dist/literal-acceptance/types.d.ts +82 -0
- package/dist/literal-acceptance/types.js +26 -0
- package/dist/policy/ceremony-dial.d.ts +67 -11
- package/dist/policy/ceremony-dial.js +174 -23
- package/dist/policy/index.d.ts +1 -0
- package/dist/policy/index.js +1 -0
- package/dist/policy/merge-approval-head.d.ts +129 -0
- package/dist/policy/merge-approval-head.js +461 -0
- package/dist/policy/require-human-merge.d.ts +5 -0
- package/dist/policy/require-human-merge.js +5 -0
- package/dist/pr-merge-readiness/ci-gate.d.ts +20 -3
- package/dist/pr-merge-readiness/ci-gate.js +65 -5
- package/dist/pr-merge-readiness/compute.d.ts +13 -0
- package/dist/pr-merge-readiness/compute.js +99 -14
- package/dist/pr-merge-readiness/gh.d.ts +49 -0
- package/dist/pr-merge-readiness/gh.js +268 -0
- package/dist/pr-merge-readiness/index.d.ts +2 -2
- package/dist/pr-merge-readiness/index.js +2 -2
- package/dist/pr-merge-readiness/test-gh-fixtures.helpers.js +4 -0
- package/dist/pr-wait-mergeable/cascade.d.ts +11 -0
- package/dist/pr-wait-mergeable/cascade.js +115 -1
- package/dist/pr-wait-mergeable/main.d.ts +4 -0
- package/dist/pr-wait-mergeable/main.js +4 -0
- package/dist/pr-wait-mergeable/types.d.ts +3 -1
- package/dist/pr-wait-mergeable/wrappers.d.ts +6 -1
- package/dist/pr-wait-mergeable/wrappers.js +7 -1
- package/dist/preflight/evaluate.d.ts +15 -1
- package/dist/preflight/evaluate.js +33 -2
- package/dist/render/framework-commands.js +4 -0
- package/dist/scope/acceptance-evidence.d.ts +76 -0
- package/dist/scope/acceptance-evidence.js +348 -0
- package/dist/scope/coverage-map.d.ts +98 -0
- package/dist/scope/coverage-map.js +558 -0
- package/dist/scope/decompose.js +125 -11
- package/dist/scope/index.d.ts +3 -0
- package/dist/scope/index.js +3 -0
- package/dist/scope/parent-lineage.d.ts +125 -0
- package/dist/scope/parent-lineage.js +626 -0
- package/dist/scope/transition.d.ts +8 -0
- package/dist/scope/transition.js +61 -2
- package/dist/session/active-cli.d.ts +79 -0
- package/dist/session/active-cli.js +382 -0
- package/dist/session/effort-budget.d.ts +130 -0
- package/dist/session/effort-budget.js +334 -0
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.js +2 -0
- package/dist/session/session-start.d.ts +6 -0
- package/dist/session/session-start.js +53 -2
- package/dist/session/verify-session-ritual.d.ts +14 -0
- package/dist/session/verify-session-ritual.js +33 -0
- package/dist/story-ready/evaluate.d.ts +11 -0
- package/dist/story-ready/evaluate.js +41 -3
- package/dist/triage/actions/candidates-log.d.ts +1 -2
- package/dist/triage/actions/candidates-log.js +37 -6
- package/dist/xbrief-migrate/migrate-project.d.ts +4 -0
- package/dist/xbrief-migrate/migrate-project.js +92 -3
- package/package.json +7 -3
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safety filters for literal acceptance commands (#3267 Greptile P1).
|
|
3
|
+
*
|
|
4
|
+
* Stored commands may originate from issue text. Before shell execution they
|
|
5
|
+
* MUST pass an allowlist of argv-shaped CLI invocations without shell metacharacters.
|
|
6
|
+
* source=task_statement is capture-only until agent promotes to verify_commands.
|
|
7
|
+
*
|
|
8
|
+
* Wrapper verbs (task/deft/directive) and package managers are further restricted
|
|
9
|
+
* to read-only / verification subcommands so ambient credentials and lifecycle
|
|
10
|
+
* mutations cannot ride an acceptance command (#3267 residual).
|
|
11
|
+
*/
|
|
12
|
+
import { EXECUTABLE_LITERAL_SOURCES } from "./types.js";
|
|
13
|
+
/** Characters that imply shell composition / expansion (refuse closed). */
|
|
14
|
+
const SHELL_META_CHARS = new Set([
|
|
15
|
+
";",
|
|
16
|
+
"|",
|
|
17
|
+
"&",
|
|
18
|
+
"`",
|
|
19
|
+
"\n",
|
|
20
|
+
"\r",
|
|
21
|
+
"<",
|
|
22
|
+
">",
|
|
23
|
+
"(",
|
|
24
|
+
")",
|
|
25
|
+
"{",
|
|
26
|
+
"}",
|
|
27
|
+
"$",
|
|
28
|
+
"\0",
|
|
29
|
+
]);
|
|
30
|
+
/**
|
|
31
|
+
* First-token allowlist for **execution** (#3267 Greptile P1 ambient-authority).
|
|
32
|
+
* Network/SCM tools (curl/gh/git/docker) are intentionally excluded — they retain
|
|
33
|
+
* ambient credentials. Capture may still record broader CLI shape; only these
|
|
34
|
+
* tokens may spawn, and wrappers/PMs require subcommand allowlists below.
|
|
35
|
+
*/
|
|
36
|
+
const ALLOWED_FIRST_TOKENS = new Set([
|
|
37
|
+
"task",
|
|
38
|
+
"deft",
|
|
39
|
+
"directive",
|
|
40
|
+
"pnpm",
|
|
41
|
+
"npm",
|
|
42
|
+
"npx",
|
|
43
|
+
"yarn",
|
|
44
|
+
"bun",
|
|
45
|
+
"vitest",
|
|
46
|
+
"true",
|
|
47
|
+
"false",
|
|
48
|
+
]);
|
|
49
|
+
/**
|
|
50
|
+
* Exact wrapper subcommands that are verification-shaped (no scope/policy/scm/swarm
|
|
51
|
+
* mutations). Additional args after these tokens are allowed (e.g. `task check --json`).
|
|
52
|
+
*/
|
|
53
|
+
const ALLOWED_WRAPPER_SUBCOMMANDS = new Set([
|
|
54
|
+
"check",
|
|
55
|
+
"doctor",
|
|
56
|
+
"help",
|
|
57
|
+
"--help",
|
|
58
|
+
"-h",
|
|
59
|
+
"--version",
|
|
60
|
+
"-v",
|
|
61
|
+
"test",
|
|
62
|
+
]);
|
|
63
|
+
/**
|
|
64
|
+
* Prefixes for wrapper verbs that stay on the verify/read surface.
|
|
65
|
+
* `verify:` / `verify-` cover task verify:* family; bare `verify ` is the space form.
|
|
66
|
+
*/
|
|
67
|
+
const ALLOWED_WRAPPER_PREFIXES = ["verify:", "verify-", "verify "];
|
|
68
|
+
/** Whether this provenance is allowed to spawn a shell (#3267). */
|
|
69
|
+
export function isExecutableLiteralSource(source) {
|
|
70
|
+
return EXECUTABLE_LITERAL_SOURCES.includes(source);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Linear-time scan: refuse shell metacharacters and non-allowlisted first tokens.
|
|
74
|
+
* Intentionally does not parse full shell grammar — fail closed on ambiguity.
|
|
75
|
+
*/
|
|
76
|
+
export function evaluateCommandSafety(command) {
|
|
77
|
+
if (typeof command !== "string" || command.trim().length === 0) {
|
|
78
|
+
return { ok: false, reason: "empty command" };
|
|
79
|
+
}
|
|
80
|
+
const trimmed = command.trim();
|
|
81
|
+
if (trimmed.length > 500) {
|
|
82
|
+
return { ok: false, reason: "command exceeds 500 characters" };
|
|
83
|
+
}
|
|
84
|
+
for (let i = 0; i < trimmed.length; i += 1) {
|
|
85
|
+
const ch = trimmed[i];
|
|
86
|
+
if (SHELL_META_CHARS.has(ch)) {
|
|
87
|
+
return {
|
|
88
|
+
ok: false,
|
|
89
|
+
reason: `shell metacharacter ${JSON.stringify(ch)} is not allowed in literal AC commands`,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
let end = 0;
|
|
94
|
+
while (end < trimmed.length && trimmed[end] !== " " && trimmed[end] !== "\t") {
|
|
95
|
+
end += 1;
|
|
96
|
+
}
|
|
97
|
+
const first = trimmed.slice(0, end).toLowerCase();
|
|
98
|
+
if (first.includes("/") || first.includes("\\") || first.includes(":")) {
|
|
99
|
+
return { ok: false, reason: "path-like first token is not allowlisted" };
|
|
100
|
+
}
|
|
101
|
+
if (!ALLOWED_FIRST_TOKENS.has(first)) {
|
|
102
|
+
return {
|
|
103
|
+
ok: false,
|
|
104
|
+
reason: `first token ${JSON.stringify(first)} is not in the literal-AC allowlist`,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const rest = trimmed.slice(end).trim();
|
|
108
|
+
// Framework wrappers: only verification / help / version subcommands (no scope/policy/merge).
|
|
109
|
+
if (first === "task" || first === "deft" || first === "directive") {
|
|
110
|
+
return evaluateWrapperSubcommand(rest);
|
|
111
|
+
}
|
|
112
|
+
// Package managers: only test/exec vitest/run test|check|--version (no install/publish/net).
|
|
113
|
+
// npx is stricter (no run/exec registry forms) — see evaluatePackageManagerArgs.
|
|
114
|
+
if (first === "pnpm" ||
|
|
115
|
+
first === "npm" ||
|
|
116
|
+
first === "npx" ||
|
|
117
|
+
first === "yarn" ||
|
|
118
|
+
first === "bun") {
|
|
119
|
+
return evaluatePackageManagerArgs(rest, first);
|
|
120
|
+
}
|
|
121
|
+
// vitest first-token: allow run / related test args only (no watch/ui).
|
|
122
|
+
if (first === "vitest") {
|
|
123
|
+
return evaluateVitestArgs(rest);
|
|
124
|
+
}
|
|
125
|
+
return { ok: true, reason: null };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Restrict task/deft/directive to verification-shaped subcommands.
|
|
129
|
+
* Fail closed on scope/policy/swarm/pr/scm/lifecycle mutations.
|
|
130
|
+
*/
|
|
131
|
+
function evaluateWrapperSubcommand(rest) {
|
|
132
|
+
if (rest.length === 0) {
|
|
133
|
+
return {
|
|
134
|
+
ok: false,
|
|
135
|
+
reason: "wrapper verb (task/deft/directive) requires a restricted verification subcommand",
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
const low = rest.toLowerCase();
|
|
139
|
+
// First subcommand token (before flags/args).
|
|
140
|
+
let subEnd = 0;
|
|
141
|
+
while (subEnd < low.length && low[subEnd] !== " " && low[subEnd] !== "\t") {
|
|
142
|
+
subEnd += 1;
|
|
143
|
+
}
|
|
144
|
+
const sub = low.slice(0, subEnd);
|
|
145
|
+
if (ALLOWED_WRAPPER_SUBCOMMANDS.has(sub)) {
|
|
146
|
+
return { ok: true, reason: null };
|
|
147
|
+
}
|
|
148
|
+
for (const prefix of ALLOWED_WRAPPER_PREFIXES) {
|
|
149
|
+
if (low.startsWith(prefix)) {
|
|
150
|
+
return { ok: true, reason: null };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
ok: false,
|
|
155
|
+
reason: "wrapper subcommand must be check|doctor|verify:*|help|--version " +
|
|
156
|
+
"(scope/policy/swarm/scm/merge and other ambient-authority verbs denied)",
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Package-manager subcommand allowlist (no install/publish/exec of arbitrary bins).
|
|
161
|
+
* `npx` is stricter than npm/pnpm/yarn/bun: it must not accept `run`/`exec` forms that
|
|
162
|
+
* resolve arbitrary registry packages with inherited env (Greptile conf residual).
|
|
163
|
+
*/
|
|
164
|
+
function evaluatePackageManagerArgs(rest, firstToken) {
|
|
165
|
+
if (rest.length === 0) {
|
|
166
|
+
return { ok: false, reason: "package manager requires a restricted subcommand" };
|
|
167
|
+
}
|
|
168
|
+
const low = rest.toLowerCase();
|
|
169
|
+
// npx: only vitest (direct) or version/help — no `npx run` / `npx exec <pkg>` registry path.
|
|
170
|
+
if (firstToken === "npx") {
|
|
171
|
+
if (low === "--version" || low === "-v" || low === "--help" || low === "-h") {
|
|
172
|
+
return { ok: true, reason: null };
|
|
173
|
+
}
|
|
174
|
+
if (low === "vitest" || low.startsWith("vitest ")) {
|
|
175
|
+
const after = low === "vitest" ? "" : low.slice("vitest".length).trim();
|
|
176
|
+
return evaluateVitestArgs(after);
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
ok: false,
|
|
180
|
+
reason: "npx is limited to vitest|--version|--help " +
|
|
181
|
+
"(npx run/exec/registry packages denied for ambient-authority)",
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
// exec: only vitest (not deft/task — those re-open wrapper ambient authority).
|
|
185
|
+
if (low.startsWith("exec ")) {
|
|
186
|
+
const afterExec = low.slice("exec ".length).trim();
|
|
187
|
+
if (afterExec === "vitest" || afterExec.startsWith("vitest ")) {
|
|
188
|
+
const after = afterExec === "vitest" ? "" : afterExec.slice("vitest".length).trim();
|
|
189
|
+
return evaluateVitestArgs(after);
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
ok: false,
|
|
193
|
+
reason: "package-manager exec is limited to vitest " +
|
|
194
|
+
"(exec of deft/task/other bins denied for ambient-authority)",
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
if (low.startsWith("run vitest")) {
|
|
198
|
+
const after = low.slice("run vitest".length).trim();
|
|
199
|
+
return evaluateVitestArgs(after.length > 0 ? `run ${after}` : "run");
|
|
200
|
+
}
|
|
201
|
+
const allowedPm = low === "test" ||
|
|
202
|
+
low === "--version" ||
|
|
203
|
+
low === "-v" ||
|
|
204
|
+
low.startsWith("test ") ||
|
|
205
|
+
low.startsWith("run test") ||
|
|
206
|
+
low.startsWith("run check");
|
|
207
|
+
if (!allowedPm) {
|
|
208
|
+
return {
|
|
209
|
+
ok: false,
|
|
210
|
+
reason: "package-manager args must be test|exec vitest|run test|run check|--version " +
|
|
211
|
+
"(arbitrary scripts/network install denied for ambient-authority)",
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return { ok: true, reason: null };
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Vitest args: only non-interactive run paths. Deny watch/ui/browser hang modes.
|
|
218
|
+
*/
|
|
219
|
+
function evaluateVitestArgs(rest) {
|
|
220
|
+
const low = rest.trim().toLowerCase();
|
|
221
|
+
if (low.length === 0) {
|
|
222
|
+
// bare `vitest` defaults to watch in many setups — refuse closed.
|
|
223
|
+
return {
|
|
224
|
+
ok: false,
|
|
225
|
+
reason: "vitest requires explicit run (bare vitest defaults to watch; denied)",
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
for (const bad of ["watch", "ui", "browser", "--watch", "--ui", "--browser", "dev"]) {
|
|
229
|
+
if (low === bad ||
|
|
230
|
+
low.startsWith(`${bad} `) ||
|
|
231
|
+
low.endsWith(` ${bad}`) ||
|
|
232
|
+
low.includes(` ${bad} `)) {
|
|
233
|
+
return {
|
|
234
|
+
ok: false,
|
|
235
|
+
reason: `vitest ${bad} is denied (hang/interactive mode; use run)`,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (low === "run" ||
|
|
240
|
+
low.startsWith("run ") ||
|
|
241
|
+
low === "--version" ||
|
|
242
|
+
low === "-v" ||
|
|
243
|
+
low.startsWith("--run")) {
|
|
244
|
+
return { ok: true, reason: null };
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
ok: false,
|
|
248
|
+
reason: "vitest args must be run|--version (watch/ui/network denied for ambient-authority)",
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=safety.js.map
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Literal acceptance-command verification (#3267).
|
|
3
|
+
*
|
|
4
|
+
* Capture exact stated shell commands from the task statement at intake;
|
|
5
|
+
* run them verbatim before done. Self-chosen verification is supplementary.
|
|
6
|
+
* Extends #973 machine-verifiable-spec. Survives ceremony dial rapid/minimal
|
|
7
|
+
* (#3214) — verification depth is constant (#3156).
|
|
8
|
+
*/
|
|
9
|
+
/** Where a literal command was recovered from. */
|
|
10
|
+
export type LiteralAcceptanceSource = "task_statement" | "verify_commands" | "plan_item" | "explicit" | "metadata";
|
|
11
|
+
/**
|
|
12
|
+
* Sources trusted for automatic shell execution (#3267 Greptile P1).
|
|
13
|
+
* `task_statement` (raw issue/task text) is capture-only until an agent promotes
|
|
14
|
+
* the exact command into swarm.verify_commands / plan item / explicit metadata.
|
|
15
|
+
*/
|
|
16
|
+
export declare const EXECUTABLE_LITERAL_SOURCES: readonly LiteralAcceptanceSource[];
|
|
17
|
+
/**
|
|
18
|
+
* One executable acceptance command exactly as stated (no paraphrase).
|
|
19
|
+
* `command` is the shell string to run with the same flags/cwd as written.
|
|
20
|
+
*/
|
|
21
|
+
export interface LiteralAcceptanceCommand {
|
|
22
|
+
/** Exact command string from the task statement (not reworded). */
|
|
23
|
+
readonly command: string;
|
|
24
|
+
/**
|
|
25
|
+
* Working directory relative to project root when stated; null/omit = project root.
|
|
26
|
+
* Absolute paths are allowed when the statement uses them.
|
|
27
|
+
*/
|
|
28
|
+
readonly cwd?: string | null;
|
|
29
|
+
/** Expected stdout substring when the statement names expected output. */
|
|
30
|
+
readonly expectedStdout?: string | null;
|
|
31
|
+
/** Expected process exit code (default 0). */
|
|
32
|
+
readonly expectedExitCode?: number;
|
|
33
|
+
readonly source: LiteralAcceptanceSource;
|
|
34
|
+
/** Short provenance (heading, field path, or line context). */
|
|
35
|
+
readonly sourceSpan?: string | null;
|
|
36
|
+
}
|
|
37
|
+
/** Result of running one stored command. */
|
|
38
|
+
export interface LiteralAcceptanceRunResult {
|
|
39
|
+
readonly command: string;
|
|
40
|
+
readonly cwd: string;
|
|
41
|
+
readonly exitCode: number;
|
|
42
|
+
readonly stdout: string;
|
|
43
|
+
readonly stderr: string;
|
|
44
|
+
readonly ok: boolean;
|
|
45
|
+
readonly detail: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Shell-shaped command that was refused by the safety allowlist (#3267 residual).
|
|
49
|
+
* Operators must see these — silent drop hides ambient-authority / shape mistakes.
|
|
50
|
+
*/
|
|
51
|
+
export interface RejectedLiteralCommand {
|
|
52
|
+
readonly command: string;
|
|
53
|
+
readonly reason: string;
|
|
54
|
+
readonly sourceSpan?: string | null;
|
|
55
|
+
}
|
|
56
|
+
/** Aggregate evaluate / done-gate result. */
|
|
57
|
+
export interface LiteralAcceptanceGateResult {
|
|
58
|
+
readonly ok: boolean;
|
|
59
|
+
/** 0 = pass or no commands; 1 = command failed; 2 = config / input error. */
|
|
60
|
+
readonly code: 0 | 1 | 2;
|
|
61
|
+
readonly message: string;
|
|
62
|
+
readonly commands: readonly LiteralAcceptanceCommand[];
|
|
63
|
+
readonly runs: readonly LiteralAcceptanceRunResult[];
|
|
64
|
+
/** Safety-rejected shell-shaped lines (fail-loud ledger; may be empty). */
|
|
65
|
+
readonly rejected?: readonly RejectedLiteralCommand[];
|
|
66
|
+
}
|
|
67
|
+
/** Metadata key for operator-visible rejected command ledger (#3267). */
|
|
68
|
+
export declare const LITERAL_ACCEPTANCE_REJECTED_METADATA_KEY: "literal_acceptance_rejected";
|
|
69
|
+
/** Injectable shell runner for tests (default: spawnSync shell). */
|
|
70
|
+
export type LiteralAcceptanceRunner = (input: {
|
|
71
|
+
readonly command: string;
|
|
72
|
+
readonly cwd: string;
|
|
73
|
+
}) => {
|
|
74
|
+
readonly exitCode: number;
|
|
75
|
+
readonly stdout: string;
|
|
76
|
+
readonly stderr: string;
|
|
77
|
+
};
|
|
78
|
+
/** Metadata key on plan.metadata for captured literal commands (#3267). */
|
|
79
|
+
export declare const LITERAL_ACCEPTANCE_METADATA_KEY: "literal_acceptance_commands";
|
|
80
|
+
/** Alternate camelCase key accepted on read. */
|
|
81
|
+
export declare const LITERAL_ACCEPTANCE_METADATA_KEY_CAMEL: "literalAcceptanceCommands";
|
|
82
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Literal acceptance-command verification (#3267).
|
|
3
|
+
*
|
|
4
|
+
* Capture exact stated shell commands from the task statement at intake;
|
|
5
|
+
* run them verbatim before done. Self-chosen verification is supplementary.
|
|
6
|
+
* Extends #973 machine-verifiable-spec. Survives ceremony dial rapid/minimal
|
|
7
|
+
* (#3214) — verification depth is constant (#3156).
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Sources trusted for automatic shell execution (#3267 Greptile P1).
|
|
11
|
+
* `task_statement` (raw issue/task text) is capture-only until an agent promotes
|
|
12
|
+
* the exact command into swarm.verify_commands / plan item / explicit metadata.
|
|
13
|
+
*/
|
|
14
|
+
export const EXECUTABLE_LITERAL_SOURCES = [
|
|
15
|
+
"verify_commands",
|
|
16
|
+
"plan_item",
|
|
17
|
+
"explicit",
|
|
18
|
+
"metadata",
|
|
19
|
+
];
|
|
20
|
+
/** Metadata key for operator-visible rejected command ledger (#3267). */
|
|
21
|
+
export const LITERAL_ACCEPTANCE_REJECTED_METADATA_KEY = "literal_acceptance_rejected";
|
|
22
|
+
/** Metadata key on plan.metadata for captured literal commands (#3267). */
|
|
23
|
+
export const LITERAL_ACCEPTANCE_METADATA_KEY = "literal_acceptance_commands";
|
|
24
|
+
/** Alternate camelCase key accepted on read. */
|
|
25
|
+
export const LITERAL_ACCEPTANCE_METADATA_KEY_CAMEL = "literalAcceptanceCommands";
|
|
26
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Ceremony dial (#3214): ritual depth = f(task size × model tier × project shape).
|
|
2
|
+
* Ceremony dial (#3214 / #3263): ritual depth = f(task size × model tier × project shape).
|
|
3
3
|
*
|
|
4
4
|
* Selection policy over existing pieces — not a new subsystem.
|
|
5
5
|
* Composes:
|
|
@@ -7,11 +7,15 @@
|
|
|
7
7
|
* - #3014 minimal consumer AGENTS profile (research pointer; not yet a shipped deposit)
|
|
8
8
|
* - effort estimate (#1581), model routing (#1976/#818), host capability (#1461)
|
|
9
9
|
*
|
|
10
|
-
* Two-stage dial (#3214 design note / #1581 ordering):
|
|
11
|
-
* cold-start / incomplete
|
|
12
|
-
*
|
|
10
|
+
* Two-stage dial (#3214 design note / #1581 ordering) with tier-conditional cold-start (#3263):
|
|
11
|
+
* cold-start / incomplete size → **tier-conditional**:
|
|
12
|
+
* frontier (or unknown tier) → rapid; mid/low → standard (not rapid)
|
|
13
|
+
* escalate when evidence arrives (provisional M/L size, full matrix)
|
|
13
14
|
* Full matrix: S × frontier → rapid; non-project → minimal; else scales up.
|
|
14
15
|
* Override always available via plan.policy.ceremonyDial.override; audited on write.
|
|
16
|
+
*
|
|
17
|
+
* Audit path (#3263): session:start records depth + provisional reasons on
|
|
18
|
+
* `.deft/ritual-state.json` under `ceremony_dial` — use `readCeremonyDialAudit`.
|
|
15
19
|
*/
|
|
16
20
|
/** Canonical dotted policy field name. */
|
|
17
21
|
export declare const FIELD_CEREMONY_DIAL = "plan.policy.ceremonyDial";
|
|
@@ -60,6 +64,11 @@ export interface CeremonyDialProfile {
|
|
|
60
64
|
readonly skipFatPath: boolean;
|
|
61
65
|
/** How much lifecycle / history write budget this depth intends. */
|
|
62
66
|
readonly lifecycleWrites: "minimal" | "light" | "full";
|
|
67
|
+
/**
|
|
68
|
+
* Literal acceptance-command verification is always required (#3267 / #3156).
|
|
69
|
+
* Ceremony dial never skips capture+verbatim run — including rapid/minimal.
|
|
70
|
+
*/
|
|
71
|
+
readonly literalAcceptanceRequired: true;
|
|
63
72
|
readonly label: string;
|
|
64
73
|
}
|
|
65
74
|
export type CeremonyDialSource = "override" | "matrix" | "default" | "disabled" | "typed" | "default-on-error";
|
|
@@ -97,25 +106,38 @@ export declare function normalizeCeremonyTaskSize(raw: unknown): CeremonyTaskSiz
|
|
|
97
106
|
export declare function normalizeCeremonyModelTier(raw: unknown): CeremonyModelTier | null;
|
|
98
107
|
export declare function normalizeCeremonyProjectShape(raw: unknown): CeremonyProjectShape | null;
|
|
99
108
|
/**
|
|
100
|
-
*
|
|
109
|
+
* Tier-conditional cold-start depth when task size is incomplete (#3263).
|
|
110
|
+
*
|
|
111
|
+
* Mid/low models benefit from structure on hard tasks and should not cold-start
|
|
112
|
+
* at rapid (start-light / escalate-too-late signature). Frontier recovers from a
|
|
113
|
+
* light start. Unknown tier stays rapid (optimistic cold default; pass
|
|
114
|
+
* `--model-tier` / `DEFT_CEREMONY_MODEL_TIER` to unlock the mid/low floor).
|
|
115
|
+
*
|
|
116
|
+
* Escalate-on-evidence still applies when size later arrives (full matrix).
|
|
117
|
+
*/
|
|
118
|
+
export declare function selectCeremonyColdStartDepth(modelTier: CeremonyModelTier | null | undefined): CeremonyDepth;
|
|
119
|
+
/**
|
|
120
|
+
* Two-stage / partial-evidence selection when size or tier is missing
|
|
121
|
+
* (#3214 design note / #3263 tier-conditional cold-start).
|
|
101
122
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* Does not invent plan-item effort (#1581 post-planning only).
|
|
123
|
+
* Cold incomplete size is tier-conditional (#3263): mid/low → standard, frontier
|
|
124
|
+
* or unknown → rapid. When size is known without tier, escalate on substantial
|
|
125
|
+
* size (apps-bank safety). Does not invent plan-item effort (#1581 post-planning only).
|
|
105
126
|
*/
|
|
106
127
|
export declare function selectCeremonyDepthFromPartialEvidence(inputs: {
|
|
107
128
|
readonly taskSize: CeremonyTaskSize | null;
|
|
108
129
|
readonly modelTier: CeremonyModelTier | null;
|
|
109
130
|
}): CeremonyDepth;
|
|
110
131
|
/**
|
|
111
|
-
* Pure default matrix (#3214 acceptance +
|
|
132
|
+
* Pure default matrix (#3214 acceptance + #3263 tier-conditional cold-start):
|
|
112
133
|
* - non-project → minimal (#3014 direction)
|
|
113
134
|
* - S × frontier → rapid (strategies/rapid.md)
|
|
114
135
|
* - S × mid → standard (mid-tier gains from structure)
|
|
115
136
|
* - S × low → elevated
|
|
116
137
|
* - M × low → elevated; M otherwise → standard
|
|
117
138
|
* - L/XL → elevated (except L × frontier stays standard)
|
|
118
|
-
* - Incomplete size
|
|
139
|
+
* - Incomplete size → tier-conditional cold-start (#3263): mid/low → standard; frontier/unknown → rapid
|
|
140
|
+
* - Size known, tier missing → escalate on M/L (partial evidence)
|
|
119
141
|
*/
|
|
120
142
|
export declare function selectCeremonyDepthFromMatrix(inputs: CeremonyDialInputs): CeremonyDepth;
|
|
121
143
|
export interface SelectCeremonyDepthOptions {
|
|
@@ -126,7 +148,7 @@ export interface SelectCeremonyDepthOptions {
|
|
|
126
148
|
* Deterministic depth selection (pure; no IO).
|
|
127
149
|
*
|
|
128
150
|
* Precedence: disabled → standard; override → forced depth; else matrix on inputs;
|
|
129
|
-
* empty inputs → **rapid** (
|
|
151
|
+
* empty inputs → **rapid** (unknown-tier cold default; #3263 mid/low need modelTier set).
|
|
130
152
|
*/
|
|
131
153
|
export declare function selectCeremonyDepth(options?: SelectCeremonyDepthOptions): CeremonyDialSelection;
|
|
132
154
|
export interface ResolveCeremonyDialOptions {
|
|
@@ -230,4 +252,38 @@ export declare function resolveSessionCeremonyDialInputs(projectRoot: string, ex
|
|
|
230
252
|
readonly inputs: CeremonyDialInputs;
|
|
231
253
|
readonly provisional: ProvisionalCeremonyEstimate;
|
|
232
254
|
};
|
|
255
|
+
export interface CeremonyDialAuditProvisional {
|
|
256
|
+
readonly taskSize: CeremonyTaskSize | null;
|
|
257
|
+
readonly modelTier: CeremonyModelTier | null;
|
|
258
|
+
readonly projectShape: CeremonyProjectShape | null;
|
|
259
|
+
readonly reasons: readonly string[];
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Snapshot of dial selection recorded on `.deft/ritual-state.json` at session:start.
|
|
263
|
+
* Operators audit failed-task depth / provisional reasons without re-running ritual.
|
|
264
|
+
*/
|
|
265
|
+
export interface CeremonyDialAuditSnapshot {
|
|
266
|
+
readonly path: string;
|
|
267
|
+
readonly depth: CeremonyDepth | null;
|
|
268
|
+
readonly source: string | null;
|
|
269
|
+
readonly inputs: {
|
|
270
|
+
readonly taskSize: CeremonyTaskSize | null;
|
|
271
|
+
readonly modelTier: CeremonyModelTier | null;
|
|
272
|
+
readonly projectShape: CeremonyProjectShape | null;
|
|
273
|
+
} | null;
|
|
274
|
+
readonly provisional: CeremonyDialAuditProvisional | null;
|
|
275
|
+
readonly raw: Record<string, unknown> | null;
|
|
276
|
+
readonly error: string | null;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Read ceremony dial depth + provisional reasons from ritual-state (#3263 audit path).
|
|
280
|
+
* session:start already writes `ceremony_dial` (incl. provisional) — this is the
|
|
281
|
+
* operator/read path so failed runs can confirm start-light vs escalate timing.
|
|
282
|
+
*
|
|
283
|
+
* Returns `error` when ritual-state is missing/unreadable or lacks `ceremony_dial`;
|
|
284
|
+
* does not throw.
|
|
285
|
+
*/
|
|
286
|
+
export declare function readCeremonyDialAudit(projectRoot: string): CeremonyDialAuditSnapshot;
|
|
287
|
+
/** One-line operator summary for audit tooling / failed-task forensics (#3263). */
|
|
288
|
+
export declare function formatCeremonyDialAuditLine(audit: CeremonyDialAuditSnapshot): string;
|
|
233
289
|
//# sourceMappingURL=ceremony-dial.d.ts.map
|