@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.
- package/dist/authz/actions.d.ts +6 -0
- package/dist/authz/actions.js +3 -0
- package/dist/authz/classify.js +241 -30
- package/dist/authz/decompose-apply.d.ts +81 -0
- package/dist/authz/decompose-apply.js +377 -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/check/cached-orchestrator.d.ts +26 -5
- package/dist/check/cached-orchestrator.js +228 -6
- package/dist/check/gate-lists.d.ts +10 -4
- package/dist/check/gate-lists.js +19 -5
- package/dist/check/index.d.ts +3 -2
- package/dist/check/index.js +2 -1
- package/dist/check/named-cause.d.ts +45 -0
- package/dist/check/named-cause.js +121 -0
- package/dist/check/orchestrator.js +6 -1
- package/dist/doctor/checks.d.ts +44 -0
- package/dist/doctor/checks.js +428 -2
- 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.d.ts +6 -7
- package/dist/doctor/main.js +130 -79
- 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/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 +3 -0
- package/dist/index.js +3 -0
- package/dist/init-deposit/agent-hooks.d.ts +20 -0
- package/dist/init-deposit/agent-hooks.js +51 -31
- package/dist/init-deposit/gitignore.js +2 -0
- package/dist/intake/issue-ingest.js +36 -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/ac-pass-banking.d.ts +58 -0
- package/dist/policy/ac-pass-banking.js +150 -0
- package/dist/policy/ceremony-dial.d.ts +96 -11
- package/dist/policy/ceremony-dial.js +250 -23
- package/dist/policy/index.d.ts +2 -0
- package/dist/policy/index.js +16 -1
- 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/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 +247 -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/evaluate.d.ts +50 -0
- package/dist/product-first-done-gate/evaluate.js +255 -0
- package/dist/product-first-done-gate/index.d.ts +11 -0
- package/dist/product-first-done-gate/index.js +11 -0
- package/dist/product-first-done-gate/types.d.ts +64 -0
- package/dist/product-first-done-gate/types.js +61 -0
- package/dist/render/framework-commands.js +4 -0
- package/dist/run-summary/emit.d.ts +56 -0
- package/dist/run-summary/emit.js +171 -0
- package/dist/run-summary/index.d.ts +4 -0
- package/dist/run-summary/index.js +4 -0
- package/dist/run-summary/path.d.ts +25 -0
- package/dist/run-summary/path.js +78 -0
- package/dist/run-summary/types.d.ts +76 -0
- package/dist/run-summary/types.js +21 -0
- package/dist/scope/acceptance-evidence.d.ts +110 -0
- package/dist/scope/acceptance-evidence.js +422 -0
- package/dist/scope/coverage-map.d.ts +98 -0
- package/dist/scope/coverage-map.js +558 -0
- package/dist/scope/decompose.d.ts +5 -0
- package/dist/scope/decompose.js +134 -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/ac-pass-banking.d.ts +221 -0
- package/dist/session/ac-pass-banking.js +761 -0
- package/dist/session/active-cli.d.ts +79 -0
- package/dist/session/active-cli.js +382 -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 +136 -0
- package/dist/session/effort-budget.js +352 -0
- package/dist/session/index.d.ts +7 -0
- package/dist/session/index.js +7 -0
- package/dist/session/orientation-compression.d.ts +127 -0
- package/dist/session/orientation-compression.js +425 -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 +228 -2
- package/dist/session/toolchain-preflight.d.ts +64 -0
- package/dist/session/toolchain-preflight.js +151 -0
- 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/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/vitest-runner/coverage-debt-teardown.js +16 -4
- package/dist/xbrief-migrate/migrate-project.d.ts +4 -0
- package/dist/xbrief-migrate/migrate-project.js +92 -3
- package/package.json +15 -3
|
@@ -317,6 +317,9 @@ const REMEDIATION_NO_CANDIDATES = [
|
|
|
317
317
|
* Evaluate cache freshness for the given project root.
|
|
318
318
|
*
|
|
319
319
|
* Faithful port of scripts/preflight_cache.py::evaluate().
|
|
320
|
+
* #3286 note: deposit-sha orientation no-ops live in session orientation
|
|
321
|
+
* composition (age-gated), not here — triage cache freshness is age/drift based
|
|
322
|
+
* and must not short-circuit solely on payload/templates/engine fingerprints.
|
|
320
323
|
*/
|
|
321
324
|
export function evaluate(projectRoot, options = {}) {
|
|
322
325
|
return evaluateWithContext(projectRoot, options, { afterEmptyPopulate: false });
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* plan.acceptance schema helpers (#3284).
|
|
3
|
+
*
|
|
4
|
+
* Captures stated acceptance.commands at intake; empty requires none_stated:true.
|
|
5
|
+
* Interoperates with #3267 plan.metadata.literal_acceptance_commands.
|
|
6
|
+
*/
|
|
7
|
+
import { type AcceptanceCommand, type PlanAcceptance } from "./types.js";
|
|
8
|
+
/** Validation errors for a plan.acceptance object (empty list = valid). */
|
|
9
|
+
export declare function validatePlanAcceptance(value: unknown): string[];
|
|
10
|
+
/**
|
|
11
|
+
* Read plan.acceptance when present; otherwise synthesize from #3267
|
|
12
|
+
* literal_acceptance_commands / empty+none_stated.
|
|
13
|
+
*/
|
|
14
|
+
export declare function readPlanAcceptance(plan: Record<string, unknown> | null | undefined): PlanAcceptance;
|
|
15
|
+
/** Attach a validated PlanAcceptance onto plan.acceptance + mirror to #3267 metadata. */
|
|
16
|
+
export declare function attachPlanAcceptance(plan: Record<string, unknown>, acceptance: PlanAcceptance): Record<string, unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* Build plan.acceptance from intake capture (#3284).
|
|
19
|
+
* Stated commands → none_stated:false, source_rung:stated.
|
|
20
|
+
* No stated commands → none_stated:true, source_rung:project_floor (until agent derives).
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildAcceptanceFromIntakeCapture(capturedCommands: readonly AcceptanceCommand[]): PlanAcceptance;
|
|
23
|
+
/** Stamp plan.acceptance from existing literal capture after issue ingest. */
|
|
24
|
+
export declare function stampAcceptanceFromLiteralCapture(plan: Record<string, unknown>): Record<string, unknown>;
|
|
25
|
+
//# sourceMappingURL=acceptance.d.ts.map
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* plan.acceptance schema helpers (#3284).
|
|
3
|
+
*
|
|
4
|
+
* Captures stated acceptance.commands at intake; empty requires none_stated:true.
|
|
5
|
+
* Interoperates with #3267 plan.metadata.literal_acceptance_commands.
|
|
6
|
+
*/
|
|
7
|
+
import { attachLiteralAcceptanceCommands, readStoredLiteralAcceptanceCommands, } from "../literal-acceptance/index.js";
|
|
8
|
+
import { PLAN_ACCEPTANCE_KEY, } from "./types.js";
|
|
9
|
+
function asRecord(value) {
|
|
10
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
function isNonEmptyString(value) {
|
|
16
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
17
|
+
}
|
|
18
|
+
function coerceCommands(raw) {
|
|
19
|
+
if (!Array.isArray(raw))
|
|
20
|
+
return [];
|
|
21
|
+
const out = [];
|
|
22
|
+
for (const entry of raw) {
|
|
23
|
+
if (typeof entry === "string") {
|
|
24
|
+
const command = entry.trim();
|
|
25
|
+
if (command.length > 0)
|
|
26
|
+
out.push({ command });
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const rec = asRecord(entry);
|
|
30
|
+
if (rec === null)
|
|
31
|
+
continue;
|
|
32
|
+
const command = rec.command ?? rec.cmd ?? rec.shell;
|
|
33
|
+
if (!isNonEmptyString(command))
|
|
34
|
+
continue;
|
|
35
|
+
out.push({
|
|
36
|
+
command: command.trim(),
|
|
37
|
+
cwd: isNonEmptyString(rec.cwd) ? rec.cwd.trim() : null,
|
|
38
|
+
expectedStdout: isNonEmptyString(rec.expectedStdout)
|
|
39
|
+
? rec.expectedStdout
|
|
40
|
+
: isNonEmptyString(rec.expected_stdout)
|
|
41
|
+
? rec.expected_stdout
|
|
42
|
+
: null,
|
|
43
|
+
expectedExitCode: typeof rec.expectedExitCode === "number"
|
|
44
|
+
? rec.expectedExitCode
|
|
45
|
+
: typeof rec.expected_exit_code === "number"
|
|
46
|
+
? rec.expected_exit_code
|
|
47
|
+
: 0,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
function isAcSourceRung(value) {
|
|
53
|
+
return value === "stated" || value === "derived" || value === "project_floor";
|
|
54
|
+
}
|
|
55
|
+
/** Validation errors for a plan.acceptance object (empty list = valid). */
|
|
56
|
+
export function validatePlanAcceptance(value) {
|
|
57
|
+
if (value === null || value === undefined) {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
const rec = asRecord(value);
|
|
61
|
+
if (rec === null) {
|
|
62
|
+
return ["plan.acceptance must be an object"];
|
|
63
|
+
}
|
|
64
|
+
const errors = [];
|
|
65
|
+
if ("commands" in rec && rec.commands !== undefined && !Array.isArray(rec.commands)) {
|
|
66
|
+
errors.push("plan.acceptance.commands must be an array");
|
|
67
|
+
}
|
|
68
|
+
if ("none_stated" in rec &&
|
|
69
|
+
rec.none_stated !== undefined &&
|
|
70
|
+
typeof rec.none_stated !== "boolean") {
|
|
71
|
+
errors.push("plan.acceptance.none_stated must be a boolean");
|
|
72
|
+
}
|
|
73
|
+
if ("source_rung" in rec && rec.source_rung !== undefined && !isAcSourceRung(rec.source_rung)) {
|
|
74
|
+
errors.push('plan.acceptance.source_rung must be "stated" | "derived" | "project_floor"');
|
|
75
|
+
}
|
|
76
|
+
const commands = coerceCommands(rec.commands);
|
|
77
|
+
const noneStated = rec.none_stated === true;
|
|
78
|
+
if (commands.length === 0 && !noneStated) {
|
|
79
|
+
errors.push("plan.acceptance.commands is empty but none_stated is not true — " +
|
|
80
|
+
"empty acceptance is only allowed with an explicit none_stated: true marker (#3284)");
|
|
81
|
+
}
|
|
82
|
+
if (commands.length > 0 && noneStated && rec.source_rung === "stated") {
|
|
83
|
+
errors.push("plan.acceptance: none_stated:true with source_rung:stated is contradictory " +
|
|
84
|
+
"(use source_rung:derived when commands are agent-authored under none_stated)");
|
|
85
|
+
}
|
|
86
|
+
return errors;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Read plan.acceptance when present; otherwise synthesize from #3267
|
|
90
|
+
* literal_acceptance_commands / empty+none_stated.
|
|
91
|
+
*/
|
|
92
|
+
export function readPlanAcceptance(plan) {
|
|
93
|
+
if (plan === null || plan === undefined) {
|
|
94
|
+
return { commands: [], none_stated: true, source_rung: "project_floor" };
|
|
95
|
+
}
|
|
96
|
+
const raw = plan[PLAN_ACCEPTANCE_KEY];
|
|
97
|
+
if (raw !== null && raw !== undefined) {
|
|
98
|
+
const rec = asRecord(raw);
|
|
99
|
+
if (rec !== null) {
|
|
100
|
+
const commands = coerceCommands(rec.commands);
|
|
101
|
+
const noneStated = rec.none_stated === true || (commands.length === 0 && rec.none_stated !== false);
|
|
102
|
+
let sourceRung = isAcSourceRung(rec.source_rung)
|
|
103
|
+
? rec.source_rung
|
|
104
|
+
: commands.length > 0
|
|
105
|
+
? "stated"
|
|
106
|
+
: "project_floor";
|
|
107
|
+
if (noneStated && commands.length > 0 && sourceRung === "stated") {
|
|
108
|
+
sourceRung = "derived";
|
|
109
|
+
}
|
|
110
|
+
if (noneStated && commands.length === 0) {
|
|
111
|
+
sourceRung = isAcSourceRung(rec.source_rung) ? rec.source_rung : "project_floor";
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
commands,
|
|
115
|
+
none_stated: noneStated,
|
|
116
|
+
source_rung: sourceRung,
|
|
117
|
+
derived_reason: isNonEmptyString(rec.derived_reason)
|
|
118
|
+
? rec.derived_reason
|
|
119
|
+
: isNonEmptyString(rec.derivedReason)
|
|
120
|
+
? rec.derivedReason
|
|
121
|
+
: null,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Fallback: #3267 metadata ledger.
|
|
126
|
+
const literal = readStoredLiteralAcceptanceCommands(plan);
|
|
127
|
+
if (literal.length > 0) {
|
|
128
|
+
return {
|
|
129
|
+
commands: literal.map(literalToAcceptance),
|
|
130
|
+
none_stated: false,
|
|
131
|
+
source_rung: "stated",
|
|
132
|
+
derived_reason: null,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
commands: [],
|
|
137
|
+
none_stated: true,
|
|
138
|
+
source_rung: "project_floor",
|
|
139
|
+
derived_reason: "no plan.acceptance and no literal_acceptance_commands (#3284 floor)",
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function literalToAcceptance(cmd) {
|
|
143
|
+
return {
|
|
144
|
+
command: cmd.command,
|
|
145
|
+
cwd: cmd.cwd ?? null,
|
|
146
|
+
expectedStdout: cmd.expectedStdout ?? null,
|
|
147
|
+
expectedExitCode: cmd.expectedExitCode ?? 0,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function acceptanceToLiteral(cmd, source) {
|
|
151
|
+
return {
|
|
152
|
+
command: cmd.command,
|
|
153
|
+
cwd: cmd.cwd ?? null,
|
|
154
|
+
expectedStdout: cmd.expectedStdout ?? null,
|
|
155
|
+
expectedExitCode: cmd.expectedExitCode ?? 0,
|
|
156
|
+
source,
|
|
157
|
+
sourceSpan: "plan.acceptance.commands",
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/** Attach a validated PlanAcceptance onto plan.acceptance + mirror to #3267 metadata. */
|
|
161
|
+
export function attachPlanAcceptance(plan, acceptance) {
|
|
162
|
+
const errors = validatePlanAcceptance(acceptance);
|
|
163
|
+
if (errors.length > 0) {
|
|
164
|
+
throw new Error(`attachPlanAcceptance: ${errors.join("; ")}`);
|
|
165
|
+
}
|
|
166
|
+
const serializable = {
|
|
167
|
+
commands: acceptance.commands.map((c) => {
|
|
168
|
+
const row = { command: c.command };
|
|
169
|
+
if (c.cwd)
|
|
170
|
+
row.cwd = c.cwd;
|
|
171
|
+
if (c.expectedStdout)
|
|
172
|
+
row.expectedStdout = c.expectedStdout;
|
|
173
|
+
if (typeof c.expectedExitCode === "number" && c.expectedExitCode !== 0) {
|
|
174
|
+
row.expectedExitCode = c.expectedExitCode;
|
|
175
|
+
}
|
|
176
|
+
return row;
|
|
177
|
+
}),
|
|
178
|
+
none_stated: acceptance.none_stated,
|
|
179
|
+
source_rung: acceptance.source_rung,
|
|
180
|
+
};
|
|
181
|
+
if (acceptance.derived_reason) {
|
|
182
|
+
serializable.derived_reason = acceptance.derived_reason;
|
|
183
|
+
}
|
|
184
|
+
let next = {
|
|
185
|
+
...plan,
|
|
186
|
+
[PLAN_ACCEPTANCE_KEY]: serializable,
|
|
187
|
+
};
|
|
188
|
+
// Mirror executable commands into #3267 ledger for verify:literal-ac interoperability.
|
|
189
|
+
if (acceptance.commands.length > 0) {
|
|
190
|
+
const source = acceptance.source_rung === "stated" ? "task_statement" : "explicit";
|
|
191
|
+
// derived / floor commands are agent-authored → executable source=explicit
|
|
192
|
+
const literalSource = acceptance.source_rung === "stated" ? "task_statement" : "explicit";
|
|
193
|
+
void source;
|
|
194
|
+
next = attachLiteralAcceptanceCommands(next, acceptance.commands.map((c) => acceptanceToLiteral(c, literalSource)));
|
|
195
|
+
}
|
|
196
|
+
return next;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Build plan.acceptance from intake capture (#3284).
|
|
200
|
+
* Stated commands → none_stated:false, source_rung:stated.
|
|
201
|
+
* No stated commands → none_stated:true, source_rung:project_floor (until agent derives).
|
|
202
|
+
*/
|
|
203
|
+
export function buildAcceptanceFromIntakeCapture(capturedCommands) {
|
|
204
|
+
if (capturedCommands.length === 0) {
|
|
205
|
+
return {
|
|
206
|
+
commands: [],
|
|
207
|
+
none_stated: true,
|
|
208
|
+
source_rung: "project_floor",
|
|
209
|
+
derived_reason: "no shell acceptance commands stated in task text; floor until agent derives AC (#3284 ladder)",
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
commands: capturedCommands,
|
|
214
|
+
none_stated: false,
|
|
215
|
+
source_rung: "stated",
|
|
216
|
+
derived_reason: null,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/** Stamp plan.acceptance from existing literal capture after issue ingest. */
|
|
220
|
+
export function stampAcceptanceFromLiteralCapture(plan) {
|
|
221
|
+
const literal = readStoredLiteralAcceptanceCommands(plan);
|
|
222
|
+
const acceptance = buildAcceptanceFromIntakeCapture(literal.map(literalToAcceptance));
|
|
223
|
+
// Avoid re-mirroring task_statement into verify_commands (ingest strips those).
|
|
224
|
+
const serializable = {
|
|
225
|
+
commands: acceptance.commands.map((c) => {
|
|
226
|
+
const row = { command: c.command };
|
|
227
|
+
if (c.cwd)
|
|
228
|
+
row.cwd = c.cwd;
|
|
229
|
+
if (c.expectedStdout)
|
|
230
|
+
row.expectedStdout = c.expectedStdout;
|
|
231
|
+
if (typeof c.expectedExitCode === "number" && c.expectedExitCode !== 0) {
|
|
232
|
+
row.expectedExitCode = c.expectedExitCode;
|
|
233
|
+
}
|
|
234
|
+
return row;
|
|
235
|
+
}),
|
|
236
|
+
none_stated: acceptance.none_stated,
|
|
237
|
+
source_rung: acceptance.source_rung,
|
|
238
|
+
};
|
|
239
|
+
if (acceptance.derived_reason) {
|
|
240
|
+
serializable.derived_reason = acceptance.derived_reason;
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
...plan,
|
|
244
|
+
[PLAN_ACCEPTANCE_KEY]: serializable,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=acceptance.js.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve product-first check composition mode (#3284).
|
|
3
|
+
*
|
|
4
|
+
* Priority (highest wins):
|
|
5
|
+
* 1. DEFT_CHECK_AC_ONLY / DEFT_CHECK_MODE=rapid → rapid (AC-only)
|
|
6
|
+
* 2. DEFT_CHECK_MODE=pressure|degraded or DEFT_HYGIENE_ADVISORY → pressure
|
|
7
|
+
* 3. ceremony dial depth rapid|minimal → rapid
|
|
8
|
+
* 4. hard effort budget (#3266) → pressure
|
|
9
|
+
* 5. default full
|
|
10
|
+
*/
|
|
11
|
+
import { type CeremonyDepth } from "../policy/ceremony-dial.js";
|
|
12
|
+
import { type ProductFirstCheckMode } from "./types.js";
|
|
13
|
+
export interface ResolveProductFirstCheckModeInput {
|
|
14
|
+
readonly environ?: Readonly<Record<string, string | undefined>>;
|
|
15
|
+
readonly projectRoot?: string;
|
|
16
|
+
/** Inject ceremony depth (tests); when unset, reads ritual-state audit. */
|
|
17
|
+
readonly ceremonyDepth?: CeremonyDepth | null;
|
|
18
|
+
/** Inject hard-budget detected flag (tests). */
|
|
19
|
+
readonly hardBudgetDetected?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface ProductFirstCheckModeResolution {
|
|
22
|
+
readonly mode: ProductFirstCheckMode;
|
|
23
|
+
readonly sources: readonly string[];
|
|
24
|
+
readonly hygieneAdvisory: boolean;
|
|
25
|
+
readonly acOnly: boolean;
|
|
26
|
+
/** AC remains mandatory whenever mode is not a pure no-op. */
|
|
27
|
+
readonly acMandatory: true;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resolve the active product-first check mode from env + ceremony + budget.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveProductFirstCheckMode(input?: ResolveProductFirstCheckModeInput): ProductFirstCheckModeResolution;
|
|
33
|
+
/** True when this gate id is the product AC gate. */
|
|
34
|
+
export declare function isProductAcGate(gateId: string): boolean;
|
|
35
|
+
/** True when this gate is classified as hygiene (may be advisory under pressure). */
|
|
36
|
+
export declare function isHygieneGate(gateId: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Filter / annotate gate list for the resolved mode.
|
|
39
|
+
* - rapid: only product AC gates
|
|
40
|
+
* - pressure/full: full list (pressure marks hygiene advisory at run time)
|
|
41
|
+
*/
|
|
42
|
+
export declare function applyProductFirstGateMode<T extends string | {
|
|
43
|
+
readonly task: string;
|
|
44
|
+
}>(gates: readonly T[], mode: ProductFirstCheckMode, gateIdOf?: (g: T) => string): readonly T[];
|
|
45
|
+
//# sourceMappingURL=check-mode.d.ts.map
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve product-first check composition mode (#3284).
|
|
3
|
+
*
|
|
4
|
+
* Priority (highest wins):
|
|
5
|
+
* 1. DEFT_CHECK_AC_ONLY / DEFT_CHECK_MODE=rapid → rapid (AC-only)
|
|
6
|
+
* 2. DEFT_CHECK_MODE=pressure|degraded or DEFT_HYGIENE_ADVISORY → pressure
|
|
7
|
+
* 3. ceremony dial depth rapid|minimal → rapid
|
|
8
|
+
* 4. hard effort budget (#3266) → pressure
|
|
9
|
+
* 5. default full
|
|
10
|
+
*/
|
|
11
|
+
import { CEREMONY_DEPTHS, readCeremonyDialAudit, } from "../policy/ceremony-dial.js";
|
|
12
|
+
import { detectHardEffortBudget } from "../session/effort-budget.js";
|
|
13
|
+
import { ENV_CHECK_AC_ONLY, ENV_CHECK_MODE, ENV_HYGIENE_ADVISORY, HYGIENE_GATE_ID_PREFIXES, PRODUCT_AC_GATE_ID, } from "./types.js";
|
|
14
|
+
function asCeremonyDepth(value) {
|
|
15
|
+
return typeof value === "string" && CEREMONY_DEPTHS.includes(value)
|
|
16
|
+
? value
|
|
17
|
+
: null;
|
|
18
|
+
}
|
|
19
|
+
const TRUTHY = new Set(["1", "true", "yes", "on"]);
|
|
20
|
+
function isTruthy(raw) {
|
|
21
|
+
if (raw === undefined)
|
|
22
|
+
return false;
|
|
23
|
+
return TRUTHY.has(raw.trim().toLowerCase());
|
|
24
|
+
}
|
|
25
|
+
function normalizeModeToken(raw) {
|
|
26
|
+
const t = raw.trim().toLowerCase();
|
|
27
|
+
if (t === "full" || t === "standard")
|
|
28
|
+
return "full";
|
|
29
|
+
if (t === "pressure" || t === "degraded" || t === "advisory")
|
|
30
|
+
return "pressure";
|
|
31
|
+
if (t === "rapid" || t === "minimal" || t === "ac-only" || t === "ac_only")
|
|
32
|
+
return "rapid";
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the active product-first check mode from env + ceremony + budget.
|
|
37
|
+
*/
|
|
38
|
+
export function resolveProductFirstCheckMode(input = {}) {
|
|
39
|
+
const env = input.environ ?? process.env;
|
|
40
|
+
const sources = [];
|
|
41
|
+
if (isTruthy(env[ENV_CHECK_AC_ONLY])) {
|
|
42
|
+
sources.push(`${ENV_CHECK_AC_ONLY}=truthy`);
|
|
43
|
+
return {
|
|
44
|
+
mode: "rapid",
|
|
45
|
+
sources,
|
|
46
|
+
hygieneAdvisory: true,
|
|
47
|
+
acOnly: true,
|
|
48
|
+
acMandatory: true,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const modeEnv = env[ENV_CHECK_MODE];
|
|
52
|
+
if (typeof modeEnv === "string" && modeEnv.trim().length > 0) {
|
|
53
|
+
const parsed = normalizeModeToken(modeEnv);
|
|
54
|
+
if (parsed !== null) {
|
|
55
|
+
sources.push(`${ENV_CHECK_MODE}=${modeEnv.trim()}`);
|
|
56
|
+
return {
|
|
57
|
+
mode: parsed,
|
|
58
|
+
sources,
|
|
59
|
+
hygieneAdvisory: parsed !== "full",
|
|
60
|
+
acOnly: parsed === "rapid",
|
|
61
|
+
acMandatory: true,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (isTruthy(env[ENV_HYGIENE_ADVISORY])) {
|
|
66
|
+
sources.push(`${ENV_HYGIENE_ADVISORY}=truthy`);
|
|
67
|
+
return {
|
|
68
|
+
mode: "pressure",
|
|
69
|
+
sources,
|
|
70
|
+
hygieneAdvisory: true,
|
|
71
|
+
acOnly: false,
|
|
72
|
+
acMandatory: true,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
let depth = input.ceremonyDepth;
|
|
76
|
+
if (depth === undefined && input.projectRoot !== undefined) {
|
|
77
|
+
try {
|
|
78
|
+
const audit = readCeremonyDialAudit(input.projectRoot);
|
|
79
|
+
depth = asCeremonyDepth(audit.depth);
|
|
80
|
+
if (depth !== null)
|
|
81
|
+
sources.push(`ceremony_dial.depth=${depth}`);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
depth = null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (depth === "rapid" || depth === "minimal") {
|
|
88
|
+
if (!sources.some((s) => s.startsWith("ceremony_dial"))) {
|
|
89
|
+
sources.push(`ceremonyDepth=${depth}`);
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
mode: "rapid",
|
|
93
|
+
sources,
|
|
94
|
+
hygieneAdvisory: true,
|
|
95
|
+
acOnly: true,
|
|
96
|
+
acMandatory: true,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
let hardBudget = input.hardBudgetDetected;
|
|
100
|
+
if (hardBudget === undefined) {
|
|
101
|
+
hardBudget = detectHardEffortBudget({ environ: env }).detected;
|
|
102
|
+
if (hardBudget)
|
|
103
|
+
sources.push("hard_effort_budget");
|
|
104
|
+
}
|
|
105
|
+
else if (hardBudget) {
|
|
106
|
+
sources.push("hard_effort_budget(injected)");
|
|
107
|
+
}
|
|
108
|
+
if (hardBudget === true) {
|
|
109
|
+
return {
|
|
110
|
+
mode: "pressure",
|
|
111
|
+
sources,
|
|
112
|
+
hygieneAdvisory: true,
|
|
113
|
+
acOnly: false,
|
|
114
|
+
acMandatory: true,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
sources.push("default:full");
|
|
118
|
+
return {
|
|
119
|
+
mode: "full",
|
|
120
|
+
sources,
|
|
121
|
+
hygieneAdvisory: false,
|
|
122
|
+
acOnly: false,
|
|
123
|
+
acMandatory: true,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/** True when this gate id is the product AC gate. */
|
|
127
|
+
export function isProductAcGate(gateId) {
|
|
128
|
+
return gateId === PRODUCT_AC_GATE_ID || gateId === "verify:literal-ac";
|
|
129
|
+
}
|
|
130
|
+
/** True when this gate is classified as hygiene (may be advisory under pressure). */
|
|
131
|
+
export function isHygieneGate(gateId) {
|
|
132
|
+
if (isProductAcGate(gateId))
|
|
133
|
+
return false;
|
|
134
|
+
return HYGIENE_GATE_ID_PREFIXES.includes(gateId);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Filter / annotate gate list for the resolved mode.
|
|
138
|
+
* - rapid: only product AC gates
|
|
139
|
+
* - pressure/full: full list (pressure marks hygiene advisory at run time)
|
|
140
|
+
*/
|
|
141
|
+
export function applyProductFirstGateMode(gates, mode, gateIdOf = (g) => (typeof g === "string" ? g : g.task)) {
|
|
142
|
+
if (mode === "rapid") {
|
|
143
|
+
const ac = gates.filter((g) => isProductAcGate(gateIdOf(g)));
|
|
144
|
+
return ac.length > 0 ? ac : gates.filter((g) => gateIdOf(g) === PRODUCT_AC_GATE_ID);
|
|
145
|
+
}
|
|
146
|
+
return gates;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=check-mode.js.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* evaluate verify:ac — product-first acceptance gate (#3284).
|
|
3
|
+
*
|
|
4
|
+
* Runs plan.acceptance.commands (or #3267 literal ledger) via the shared
|
|
5
|
+
* literal-acceptance runner. Records source_rung in the result message.
|
|
6
|
+
* Project floor with empty commands is a soft pass (suite gates own the floor
|
|
7
|
+
* inside full `task check`); standalone done paths still surface the rung.
|
|
8
|
+
*/
|
|
9
|
+
import { type EvaluateLiteralAcceptanceOptions, type LiteralAcceptanceGateResult } from "../literal-acceptance/index.js";
|
|
10
|
+
import type { AcSourceRung, PlanAcceptance } from "./types.js";
|
|
11
|
+
export interface VerifyAcResult extends LiteralAcceptanceGateResult {
|
|
12
|
+
readonly sourceRung: AcSourceRung;
|
|
13
|
+
readonly noneStated: boolean;
|
|
14
|
+
readonly acceptance: PlanAcceptance;
|
|
15
|
+
}
|
|
16
|
+
export interface EvaluateVerifyAcOptions extends EvaluateLiteralAcceptanceOptions {
|
|
17
|
+
/**
|
|
18
|
+
* When true, missing xBRIEF / no active scope is exit 0 (check composition).
|
|
19
|
+
* Default false for standalone done-gate use.
|
|
20
|
+
*/
|
|
21
|
+
readonly softMissingXbrief?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Check-graph mode (#3284): used by `task check` via `--soft-missing-xbrief`.
|
|
24
|
+
* - Unpromoted capture-only (task_statement) commands do not fail the graph
|
|
25
|
+
* (promotion remains a done-gate / scope:complete concern via verify:ac standalone).
|
|
26
|
+
* - Executable command failures still fail closed (product-first).
|
|
27
|
+
* - Safety-rejected ledger still fails closed.
|
|
28
|
+
*/
|
|
29
|
+
readonly checkIntegrated?: boolean;
|
|
30
|
+
/** Allow task_statement sources to execute (tests / explicit promote). */
|
|
31
|
+
readonly allowTaskStatement?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* When false, skip AC-pass banking after executable pass (#3285).
|
|
34
|
+
* Default true — first green executable AC banks a finalize checkpoint.
|
|
35
|
+
*/
|
|
36
|
+
readonly bankOnPass?: boolean;
|
|
37
|
+
/** Optional scope id override for the bank ledger (default plan.id / path). */
|
|
38
|
+
readonly bankScopeId?: string | null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Evaluate product AC from an in-memory plan.
|
|
42
|
+
*/
|
|
43
|
+
export declare function evaluateVerifyAcFromPlan(plan: Record<string, unknown>, options?: EvaluateVerifyAcOptions): VerifyAcResult;
|
|
44
|
+
/**
|
|
45
|
+
* Evaluate from xBRIEF path.
|
|
46
|
+
*/
|
|
47
|
+
export declare function evaluateVerifyAcFromPath(xbriefPath: string, options?: EvaluateVerifyAcOptions): VerifyAcResult;
|
|
48
|
+
/** Pure: product AC is required at every ceremony depth (#3284 / #3267 / #3156). */
|
|
49
|
+
export declare function isVerifyAcRequiredAtCeremonyDepth(_depth: string | null | undefined): boolean;
|
|
50
|
+
//# sourceMappingURL=evaluate.d.ts.map
|