@deftai/directive-core 0.88.0 → 0.90.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 +55 -0
- package/dist/authz/actions.js +125 -0
- package/dist/authz/classify.d.ts +23 -0
- package/dist/authz/classify.js +217 -0
- package/dist/authz/closed-verb.d.ts +42 -0
- package/dist/authz/closed-verb.js +279 -0
- package/dist/authz/evaluate.d.ts +41 -0
- package/dist/authz/evaluate.js +298 -0
- package/dist/authz/index.d.ts +15 -0
- package/dist/authz/index.js +15 -0
- package/dist/authz/origin.d.ts +28 -0
- package/dist/authz/origin.js +64 -0
- package/dist/authz/paths.d.ts +6 -0
- package/dist/authz/paths.js +19 -0
- package/dist/authz/store.d.ts +40 -0
- package/dist/authz/store.js +317 -0
- package/dist/authz/templates.d.ts +139 -0
- package/dist/authz/templates.js +241 -0
- package/dist/authz/types.d.ts +111 -0
- package/dist/authz/types.js +41 -0
- package/dist/authz/verb-classification.d.ts +44 -0
- package/dist/authz/verb-classification.js +237 -0
- package/dist/branch/evaluate.js +6 -1
- package/dist/cache/fetch.js +10 -5
- package/dist/cache/io.d.ts +9 -2
- package/dist/cache/io.js +30 -10
- package/dist/cache/task-cache/store.js +11 -7
- package/dist/capacity/backfill.js +10 -4
- package/dist/category-b-namespace/index.js +10 -4
- package/dist/codebase/default-extractor.js +3 -0
- package/dist/codebase/map.js +11 -4
- package/dist/doctor/constants.d.ts +1 -1
- package/dist/doctor/constants.js +2 -0
- package/dist/doctor/doctor-state.js +28 -4
- package/dist/doctor/flags.js +21 -1
- package/dist/doctor/index.d.ts +1 -0
- package/dist/doctor/index.js +1 -0
- package/dist/doctor/main.d.ts +10 -0
- package/dist/doctor/main.js +182 -0
- package/dist/doctor/openclaw-skills.d.ts +109 -0
- package/dist/doctor/openclaw-skills.js +463 -0
- package/dist/doctor/types.d.ts +22 -0
- package/dist/escalation/actions.d.ts +63 -0
- package/dist/escalation/actions.js +137 -0
- package/dist/escalation/index.d.ts +8 -0
- package/dist/escalation/index.js +8 -0
- package/dist/escalation/paths.d.ts +3 -0
- package/dist/escalation/paths.js +10 -0
- package/dist/escalation/store.d.ts +17 -0
- package/dist/escalation/store.js +172 -0
- package/dist/escalation/types.d.ts +73 -0
- package/dist/escalation/types.js +43 -0
- package/dist/eval/crud-telemetry.js +30 -10
- package/dist/eval/health.js +22 -7
- package/dist/eval/readback.js +11 -10
- package/dist/eval/run.js +32 -16
- package/dist/events/attribution-enrichment.js +10 -4
- package/dist/finish-loop/directive-finish-loop.d.ts +37 -0
- package/dist/finish-loop/directive-finish-loop.js +239 -0
- package/dist/finish-loop/grant-gate.d.ts +31 -0
- package/dist/finish-loop/grant-gate.js +169 -0
- package/dist/finish-loop/index.d.ts +11 -0
- package/dist/finish-loop/index.js +11 -0
- package/dist/finish-loop/main.d.ts +35 -0
- package/dist/finish-loop/main.js +365 -0
- package/dist/finish-loop/pr-finish-loop.d.ts +34 -0
- package/dist/finish-loop/pr-finish-loop.js +217 -0
- package/dist/finish-loop/progress.d.ts +17 -0
- package/dist/finish-loop/progress.js +45 -0
- package/dist/finish-loop/queue.d.ts +16 -0
- package/dist/finish-loop/queue.js +65 -0
- package/dist/finish-loop/types.d.ts +52 -0
- package/dist/finish-loop/types.js +10 -0
- package/dist/fs/contained-write.d.ts +101 -0
- package/dist/fs/contained-write.js +281 -0
- package/dist/hooks/classify/classify.d.ts +10 -0
- package/dist/hooks/classify/classify.js +37 -0
- package/dist/hooks/classify/index.d.ts +14 -0
- package/dist/hooks/classify/index.js +13 -0
- package/dist/hooks/classify/paths.d.ts +22 -0
- package/dist/hooks/classify/paths.js +72 -0
- package/dist/hooks/classify/payload.d.ts +16 -0
- package/dist/hooks/classify/payload.js +45 -0
- package/dist/hooks/classify/stdin.d.ts +12 -0
- package/dist/hooks/classify/stdin.js +63 -0
- package/dist/hooks/classify/tool-name.d.ts +18 -0
- package/dist/hooks/classify/tool-name.js +85 -0
- package/dist/hooks/classify/types.d.ts +41 -0
- package/dist/hooks/classify/types.js +7 -0
- package/dist/hooks/dispatcher.d.ts +21 -18
- package/dist/hooks/dispatcher.js +232 -168
- package/dist/hooks/fixtures/cases.d.ts +44 -0
- package/dist/hooks/fixtures/cases.js +595 -0
- package/dist/hooks/fixtures/index.d.ts +2 -0
- package/dist/hooks/fixtures/index.js +2 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.js +2 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -0
- package/dist/init-deposit/agent-hooks.js +27 -8
- package/dist/init-deposit/gitignore.js +11 -3
- package/dist/init-deposit/headless-manifest.js +12 -4
- package/dist/init-deposit/migrate.d.ts +1 -1
- package/dist/init-deposit/migrate.js +13 -3
- package/dist/init-deposit/prettierignore.js +10 -3
- package/dist/init-deposit/scaffold.js +35 -26
- package/dist/init-deposit/xbrief-projections.js +11 -4
- package/dist/intake/candidates-log.js +46 -35
- package/dist/intake/github-body-cli.d.ts +6 -0
- package/dist/intake/github-body-cli.js +17 -0
- package/dist/intake/github-body.d.ts +46 -3
- package/dist/intake/github-body.js +191 -20
- package/dist/intake/issue-emit.d.ts +1 -0
- package/dist/intake/issue-emit.js +41 -23
- package/dist/lifecycle/event-detect.js +12 -4
- package/dist/lifecycle/events.js +31 -20
- package/dist/lifecycle/index.d.ts +1 -0
- package/dist/lifecycle/index.js +1 -0
- package/dist/lifecycle/lifecycle-hygiene.js +9 -3
- package/dist/lifecycle/stats.d.ts +53 -0
- package/dist/lifecycle/stats.js +286 -0
- package/dist/packs/pack-render.js +19 -6
- package/dist/plan-sequence/store.js +11 -4
- package/dist/policy/hotfix-criteria.d.ts +79 -0
- package/dist/policy/hotfix-criteria.js +197 -0
- package/dist/policy/index.d.ts +4 -0
- package/dist/policy/index.js +31 -1
- package/dist/policy/intent-ceiling.d.ts +79 -0
- package/dist/policy/intent-ceiling.js +181 -0
- package/dist/policy/no-deft-directive.js +10 -3
- package/dist/policy/org-force-on-migration.js +9 -5
- package/dist/policy/require-human-merge.d.ts +75 -0
- package/dist/policy/require-human-merge.js +324 -0
- package/dist/policy/resolve.js +17 -6
- package/dist/policy/runtime-authority.d.ts +15 -2
- package/dist/policy/runtime-authority.js +23 -3
- package/dist/policy/write-fence.d.ts +78 -0
- package/dist/policy/write-fence.js +164 -0
- package/dist/pr-wait-mergeable/cascade.d.ts +10 -0
- package/dist/pr-wait-mergeable/cascade.js +28 -0
- package/dist/preflight/evaluate.js +10 -0
- package/dist/product-signal/consent.js +21 -5
- package/dist/product-signal/submit.js +22 -12
- package/dist/release/build-dist-runner.js +5 -2
- package/dist/release/build-dist.d.ts +19 -1
- package/dist/release/build-dist.js +50 -2
- package/dist/release/native-steps.js +7 -2
- package/dist/release/spawn.js +13 -0
- package/dist/release-e2e/git-ops.d.ts +7 -0
- package/dist/release-e2e/git-ops.js +35 -2
- package/dist/release-publish/pipeline.d.ts +13 -0
- package/dist/release-publish/pipeline.js +46 -1
- package/dist/scope/audit-log.js +19 -24
- package/dist/scope/decompose.js +10 -5
- package/dist/scope/decomposed-refs.js +18 -3
- package/dist/scope/demote.js +9 -2
- package/dist/scope/undo.js +9 -2
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.js +2 -0
- package/dist/session/process-cost-constants.d.ts +9 -0
- package/dist/session/process-cost-constants.js +11 -0
- package/dist/session/process-cost.d.ts +53 -0
- package/dist/session/process-cost.js +82 -0
- package/dist/session/release-availability.js +26 -6
- package/dist/session/ritual-sentinel.d.ts +5 -0
- package/dist/session/ritual-sentinel.js +31 -13
- package/dist/session/session-ready.d.ts +67 -0
- package/dist/session/session-ready.js +264 -0
- package/dist/session/session-start.d.ts +56 -1
- package/dist/session/session-start.js +384 -23
- package/dist/session/verify-session-ritual.d.ts +8 -0
- package/dist/session/verify-session-ritual.js +95 -35
- package/dist/staleness-tickler/state.js +26 -6
- package/dist/swarm/launch.js +13 -3
- package/dist/swarm/routing.js +9 -3
- package/dist/task-surface/index.js +24 -9
- package/dist/tool-events/classify.d.ts +20 -0
- package/dist/tool-events/classify.js +634 -0
- package/dist/tool-events/index.d.ts +10 -0
- package/dist/tool-events/index.js +10 -0
- package/dist/tool-events/summarize.d.ts +34 -0
- package/dist/tool-events/summarize.js +93 -0
- package/dist/tool-events/types.d.ts +52 -0
- package/dist/tool-events/types.js +13 -0
- package/dist/triage/bootstrap/gitignore.js +53 -10
- package/dist/triage/cache-path.js +10 -3
- package/dist/triage/welcome/summary.js +11 -4
- package/dist/triage/welcome/writers.js +45 -16
- package/dist/validate-content/validate-links.js +5 -0
- package/dist/value/readback.js +11 -6
- package/dist/vbrief-activate/activate.js +12 -4
- package/dist/vbrief-build/project-definition-io.js +14 -6
- package/dist/verify-source/contained-writes.d.ts +59 -0
- package/dist/verify-source/contained-writes.js +272 -0
- package/dist/verify-source/index.d.ts +1 -0
- package/dist/verify-source/index.js +1 -0
- package/dist/verify-source/openclaw-tier1.js +14 -1
- package/dist/verify-source/verify-stubs.js +3 -0
- package/dist/xbrief-migrate/migrate-project.js +26 -12
- package/dist/xbrief-migrate/transforms.d.ts +4 -2
- package/dist/xbrief-migrate/transforms.js +37 -14
- package/package.json +19 -3
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session:ready — one-shot mutation recovery (#2993).
|
|
3
|
+
*
|
|
4
|
+
* Composes existing APIs (does not reimplement session:start or gated verify):
|
|
5
|
+
* 1. Fast path when inspectSessionRitual(gated) is already green
|
|
6
|
+
* 2. session:start when quick-tier state is missing/stale
|
|
7
|
+
* 3. verifySessionRitual(--tier=gated) for doctor + cache_fresh
|
|
8
|
+
* 4. cache fetch-all recovery when cache_fresh is the remaining blocker
|
|
9
|
+
* 5. re-verify gated
|
|
10
|
+
*
|
|
11
|
+
* Exit 0 means a subsequent inspect/verify gated would pass (or the single
|
|
12
|
+
* remaining hard blocker is printed once).
|
|
13
|
+
*/
|
|
14
|
+
import type { GitRunner } from "./git.js";
|
|
15
|
+
import { type SessionStartOptions, type SessionStartResult } from "./session-start.js";
|
|
16
|
+
import { type InspectSessionRitualOptions, type RitualRunner, type VerifyResult, type VerifySessionRitualOptions } from "./verify-session-ritual.js";
|
|
17
|
+
export declare const SESSION_READY_FAST_PATH = "fast";
|
|
18
|
+
export declare const SESSION_READY_RECOVERED = "recovered";
|
|
19
|
+
export declare const SESSION_READY_VERIFIED = "verified";
|
|
20
|
+
export declare const SESSION_READY_FAILED = "failed";
|
|
21
|
+
export type SessionReadyPath = typeof SESSION_READY_FAST_PATH | typeof SESSION_READY_RECOVERED | typeof SESSION_READY_VERIFIED | typeof SESSION_READY_FAILED;
|
|
22
|
+
export interface SessionReadyResult {
|
|
23
|
+
readonly code: number;
|
|
24
|
+
readonly message: string;
|
|
25
|
+
readonly path: SessionReadyPath;
|
|
26
|
+
readonly lines: readonly string[];
|
|
27
|
+
/** Steps actually executed (for tests / --json). */
|
|
28
|
+
readonly steps: readonly string[];
|
|
29
|
+
readonly duration_ms: number;
|
|
30
|
+
}
|
|
31
|
+
export type CacheFetchAllSeam = (options: {
|
|
32
|
+
source: string;
|
|
33
|
+
repo: string;
|
|
34
|
+
force?: boolean;
|
|
35
|
+
cacheRoot?: string;
|
|
36
|
+
}) => unknown;
|
|
37
|
+
export interface SessionReadyOptions {
|
|
38
|
+
readonly now?: Date;
|
|
39
|
+
readonly runGit?: GitRunner;
|
|
40
|
+
readonly runner?: RitualRunner;
|
|
41
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
42
|
+
/** When set, overrides DEFT_TRIAGE_REPO / git remote inference for cache recovery. */
|
|
43
|
+
readonly repo?: string | null;
|
|
44
|
+
readonly sessionStartOptions?: Omit<SessionStartOptions, "now" | "runGit" | "env">;
|
|
45
|
+
readonly inspectRitual?: (projectRoot: string, options: InspectSessionRitualOptions) => VerifyResult;
|
|
46
|
+
readonly verifyRitual?: (projectRoot: string, options: VerifySessionRitualOptions) => VerifyResult;
|
|
47
|
+
readonly runStart?: (projectRoot: string, options: SessionStartOptions) => SessionStartResult;
|
|
48
|
+
readonly fetchAll?: CacheFetchAllSeam;
|
|
49
|
+
readonly inferRepo?: (projectRoot: string) => string | null;
|
|
50
|
+
/** Skip cache recovery even when cache_fresh failed (tests). */
|
|
51
|
+
readonly skipCacheRecovery?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** True when a gated verify failure is attributable to the cache_fresh step. */
|
|
54
|
+
export declare function isCacheFreshFailure(message: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* True readiness for PreToolUse: exit 0 without DEFT_SESSION_RITUAL_SKIP bypass.
|
|
57
|
+
* Bypassed code 0 does not make inspectSessionRitual green (#2993 Greptile P1).
|
|
58
|
+
*/
|
|
59
|
+
export declare function isGatedVerifyActuallyReady(result: VerifyResult): boolean;
|
|
60
|
+
/** Infer OWNER/NAME from DEFT_TRIAGE_REPO or git remote origin. */
|
|
61
|
+
export declare function inferSessionReadyRepo(projectRoot: string, env?: NodeJS.ProcessEnv): string | null;
|
|
62
|
+
/**
|
|
63
|
+
* One-shot recovery: leave the worktree PreToolUse-gated-inspect green, or
|
|
64
|
+
* print the single remaining blocker.
|
|
65
|
+
*/
|
|
66
|
+
export declare function runSessionReady(projectRoot: string, options?: SessionReadyOptions): SessionReadyResult;
|
|
67
|
+
//# sourceMappingURL=session-ready.d.ts.map
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session:ready — one-shot mutation recovery (#2993).
|
|
3
|
+
*
|
|
4
|
+
* Composes existing APIs (does not reimplement session:start or gated verify):
|
|
5
|
+
* 1. Fast path when inspectSessionRitual(gated) is already green
|
|
6
|
+
* 2. session:start when quick-tier state is missing/stale
|
|
7
|
+
* 3. verifySessionRitual(--tier=gated) for doctor + cache_fresh
|
|
8
|
+
* 4. cache fetch-all recovery when cache_fresh is the remaining blocker
|
|
9
|
+
* 5. re-verify gated
|
|
10
|
+
*
|
|
11
|
+
* Exit 0 means a subsequent inspect/verify gated would pass (or the single
|
|
12
|
+
* remaining hard blocker is printed once).
|
|
13
|
+
*/
|
|
14
|
+
import { execFileSync } from "node:child_process";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { cacheFetchAll } from "../cache/fetch.js";
|
|
17
|
+
import { formatFrameworkCommand } from "../render/framework-commands.js";
|
|
18
|
+
import { runSessionStart, } from "./session-start.js";
|
|
19
|
+
import { inspectSessionRitual, verifySessionRitual, } from "./verify-session-ritual.js";
|
|
20
|
+
export const SESSION_READY_FAST_PATH = "fast";
|
|
21
|
+
export const SESSION_READY_RECOVERED = "recovered";
|
|
22
|
+
export const SESSION_READY_VERIFIED = "verified";
|
|
23
|
+
export const SESSION_READY_FAILED = "failed";
|
|
24
|
+
function elapsedMs(started) {
|
|
25
|
+
return Math.max(0, Math.round(performance.now() - started));
|
|
26
|
+
}
|
|
27
|
+
/** True when a gated verify failure is attributable to the cache_fresh step. */
|
|
28
|
+
export function isCacheFreshFailure(message) {
|
|
29
|
+
return /cache_fresh|cache-fresh|cache fetch-all|cache-fresh:|stale-by-drift|stale age/i.test(message);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* True readiness for PreToolUse: exit 0 without DEFT_SESSION_RITUAL_SKIP bypass.
|
|
33
|
+
* Bypassed code 0 does not make inspectSessionRitual green (#2993 Greptile P1).
|
|
34
|
+
*/
|
|
35
|
+
export function isGatedVerifyActuallyReady(result) {
|
|
36
|
+
return result.code === 0 && !result.bypassed;
|
|
37
|
+
}
|
|
38
|
+
function bypassedReadyFailure(result) {
|
|
39
|
+
const detail = result.message.trim().length > 0
|
|
40
|
+
? result.message
|
|
41
|
+
: "session ritual verification was bypassed (DEFT_SESSION_RITUAL_SKIP)";
|
|
42
|
+
return (`${detail}\n` +
|
|
43
|
+
` session:ready refuses bypassed verification (would not pass PreToolUse inspect). ` +
|
|
44
|
+
`Unset DEFT_SESSION_RITUAL_SKIP and re-run \`${readyCommand()}\`.`);
|
|
45
|
+
}
|
|
46
|
+
function normaliseRepoUrl(url) {
|
|
47
|
+
if (!url)
|
|
48
|
+
return null;
|
|
49
|
+
const cleaned = url
|
|
50
|
+
.trim()
|
|
51
|
+
.replace(/\/$/, "")
|
|
52
|
+
.replace(/\.git$/, "");
|
|
53
|
+
const match = cleaned.match(/^(?:(?:https?|ssh|git):\/\/)?(?:[^/@]+@)?github\.com[:/]+([^/]+)\/([^/]+)/i);
|
|
54
|
+
if (!match)
|
|
55
|
+
return null;
|
|
56
|
+
const owner = match[1];
|
|
57
|
+
const repo = match[2];
|
|
58
|
+
if (owner && repo)
|
|
59
|
+
return `${owner}/${repo}`;
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
/** Infer OWNER/NAME from DEFT_TRIAGE_REPO or git remote origin. */
|
|
63
|
+
export function inferSessionReadyRepo(projectRoot, env = process.env) {
|
|
64
|
+
const fromEnv = (env.DEFT_TRIAGE_REPO ?? "").trim();
|
|
65
|
+
if (fromEnv.length > 0 && fromEnv.includes("/"))
|
|
66
|
+
return fromEnv;
|
|
67
|
+
try {
|
|
68
|
+
const stdout = execFileSync("git", ["remote", "get-url", "origin"], {
|
|
69
|
+
cwd: projectRoot,
|
|
70
|
+
encoding: "utf8",
|
|
71
|
+
timeout: 10000,
|
|
72
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
73
|
+
});
|
|
74
|
+
return normaliseRepoUrl(stdout.trim());
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function readyCommand() {
|
|
81
|
+
return formatFrameworkCommand(["session:ready"]);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* One-shot recovery: leave the worktree PreToolUse-gated-inspect green, or
|
|
85
|
+
* print the single remaining blocker.
|
|
86
|
+
*/
|
|
87
|
+
export function runSessionReady(projectRoot, options = {}) {
|
|
88
|
+
const started = performance.now();
|
|
89
|
+
const now = options.now ?? new Date();
|
|
90
|
+
const env = options.env ?? process.env;
|
|
91
|
+
const lines = [];
|
|
92
|
+
const steps = [];
|
|
93
|
+
const inspect = options.inspectRitual ?? ((root, opts) => inspectSessionRitual(root, opts));
|
|
94
|
+
const verify = options.verifyRitual ?? ((root, opts) => verifySessionRitual(root, opts));
|
|
95
|
+
const start = options.runStart ?? ((root, opts) => runSessionStart(root, opts));
|
|
96
|
+
const fetchAll = options.fetchAll ?? cacheFetchAll;
|
|
97
|
+
const inferRepo = options.inferRepo ?? ((root) => inferSessionReadyRepo(root, env));
|
|
98
|
+
// --- Fast path: already green for PreToolUse gated inspect ---
|
|
99
|
+
const gatedInspect = inspect(projectRoot, {
|
|
100
|
+
tier: "gated",
|
|
101
|
+
posture: "mutation",
|
|
102
|
+
now,
|
|
103
|
+
runGit: options.runGit,
|
|
104
|
+
});
|
|
105
|
+
if (gatedInspect.code === 0) {
|
|
106
|
+
const message = "OK session ready (gated ritual already fresh).";
|
|
107
|
+
lines.push(message);
|
|
108
|
+
return {
|
|
109
|
+
code: 0,
|
|
110
|
+
message,
|
|
111
|
+
path: SESSION_READY_FAST_PATH,
|
|
112
|
+
lines,
|
|
113
|
+
steps,
|
|
114
|
+
duration_ms: elapsedMs(started),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// --- Ensure quick-tier ritual state when missing / stale / drifted ---
|
|
118
|
+
const quickInspect = inspect(projectRoot, {
|
|
119
|
+
tier: "quick",
|
|
120
|
+
posture: "mutation",
|
|
121
|
+
now,
|
|
122
|
+
runGit: options.runGit,
|
|
123
|
+
});
|
|
124
|
+
if (quickInspect.code !== 0) {
|
|
125
|
+
steps.push("session:start");
|
|
126
|
+
const startResult = start(projectRoot, {
|
|
127
|
+
...options.sessionStartOptions,
|
|
128
|
+
now,
|
|
129
|
+
runGit: options.runGit,
|
|
130
|
+
env,
|
|
131
|
+
writeHistory: options.sessionStartOptions?.writeHistory ?? false,
|
|
132
|
+
});
|
|
133
|
+
for (const line of startResult.lines) {
|
|
134
|
+
lines.push(line);
|
|
135
|
+
}
|
|
136
|
+
if (startResult.code !== 0) {
|
|
137
|
+
const message = startResult.lines.join("\n").trim() ||
|
|
138
|
+
`session:start failed (exit ${startResult.code}). Recovery: run \`${readyCommand()}\` again after fixing the blocker.`;
|
|
139
|
+
lines.push(message);
|
|
140
|
+
return {
|
|
141
|
+
code: startResult.code === 0 ? 1 : startResult.code,
|
|
142
|
+
message,
|
|
143
|
+
path: SESSION_READY_FAILED,
|
|
144
|
+
lines,
|
|
145
|
+
steps,
|
|
146
|
+
duration_ms: elapsedMs(started),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// --- Gated verify (lazy doctor + cache_fresh) ---
|
|
151
|
+
steps.push("verify:session-ritual:gated");
|
|
152
|
+
const verifyOpts = {
|
|
153
|
+
tier: "gated",
|
|
154
|
+
posture: "mutation",
|
|
155
|
+
now,
|
|
156
|
+
runGit: options.runGit,
|
|
157
|
+
runner: options.runner,
|
|
158
|
+
};
|
|
159
|
+
let verifyResult = verify(projectRoot, verifyOpts);
|
|
160
|
+
if (isGatedVerifyActuallyReady(verifyResult)) {
|
|
161
|
+
const message = "OK session ready (gated ritual verified).";
|
|
162
|
+
lines.push(message);
|
|
163
|
+
return {
|
|
164
|
+
code: 0,
|
|
165
|
+
message,
|
|
166
|
+
path: SESSION_READY_VERIFIED,
|
|
167
|
+
lines,
|
|
168
|
+
steps,
|
|
169
|
+
duration_ms: elapsedMs(started),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
if (verifyResult.code === 0 && verifyResult.bypassed) {
|
|
173
|
+
const message = bypassedReadyFailure(verifyResult);
|
|
174
|
+
lines.push(message);
|
|
175
|
+
return {
|
|
176
|
+
code: 1,
|
|
177
|
+
message,
|
|
178
|
+
path: SESSION_READY_FAILED,
|
|
179
|
+
lines,
|
|
180
|
+
steps,
|
|
181
|
+
duration_ms: elapsedMs(started),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
// --- Cache recovery when cache_fresh is the remaining blocker ---
|
|
185
|
+
if (!options.skipCacheRecovery && isCacheFreshFailure(verifyResult.message)) {
|
|
186
|
+
const repo = options.repo !== undefined ? options.repo : inferRepo(projectRoot);
|
|
187
|
+
if (repo === null || repo.length === 0) {
|
|
188
|
+
const message = `${verifyResult.message}\n` +
|
|
189
|
+
` Recovery: set DEFT_TRIAGE_REPO=OWNER/NAME or run \`deft cache fetch-all --source github-issue --repo OWNER/NAME --force\`, then \`${readyCommand()}\`.`;
|
|
190
|
+
lines.push(message);
|
|
191
|
+
return {
|
|
192
|
+
code: 1,
|
|
193
|
+
message,
|
|
194
|
+
path: SESSION_READY_FAILED,
|
|
195
|
+
lines,
|
|
196
|
+
steps,
|
|
197
|
+
duration_ms: elapsedMs(started),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
steps.push("cache:fetch-all");
|
|
201
|
+
try {
|
|
202
|
+
fetchAll({
|
|
203
|
+
source: "github-issue",
|
|
204
|
+
repo,
|
|
205
|
+
force: true,
|
|
206
|
+
cacheRoot: join(projectRoot, ".deft-cache"),
|
|
207
|
+
});
|
|
208
|
+
lines.push(`[session:ready] cache fetch-all completed for ${repo} (--force).`);
|
|
209
|
+
}
|
|
210
|
+
catch (cause) {
|
|
211
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
212
|
+
const message = `session:ready cache recovery failed: ${detail}\n` +
|
|
213
|
+
` Recovery: run \`deft cache fetch-all --source github-issue --repo ${repo} --force\`, then \`${readyCommand()}\`.`;
|
|
214
|
+
lines.push(message);
|
|
215
|
+
return {
|
|
216
|
+
code: 1,
|
|
217
|
+
message,
|
|
218
|
+
path: SESSION_READY_FAILED,
|
|
219
|
+
lines,
|
|
220
|
+
steps,
|
|
221
|
+
duration_ms: elapsedMs(started),
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
steps.push("verify:session-ritual:gated:retry");
|
|
225
|
+
verifyResult = verify(projectRoot, verifyOpts);
|
|
226
|
+
if (isGatedVerifyActuallyReady(verifyResult)) {
|
|
227
|
+
const message = "OK session ready (recovered via cache refresh).";
|
|
228
|
+
lines.push(message);
|
|
229
|
+
return {
|
|
230
|
+
code: 0,
|
|
231
|
+
message,
|
|
232
|
+
path: SESSION_READY_RECOVERED,
|
|
233
|
+
lines,
|
|
234
|
+
steps,
|
|
235
|
+
duration_ms: elapsedMs(started),
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
if (verifyResult.code === 0 && verifyResult.bypassed) {
|
|
239
|
+
const message = bypassedReadyFailure(verifyResult);
|
|
240
|
+
lines.push(message);
|
|
241
|
+
return {
|
|
242
|
+
code: 1,
|
|
243
|
+
message,
|
|
244
|
+
path: SESSION_READY_FAILED,
|
|
245
|
+
lines,
|
|
246
|
+
steps,
|
|
247
|
+
duration_ms: elapsedMs(started),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// --- Hard failure: surface the single remaining blocker ---
|
|
252
|
+
const message = `${verifyResult.message}\n` +
|
|
253
|
+
` Remaining blocker after session:ready. Fix the step above, then re-run \`${readyCommand()}\`.`;
|
|
254
|
+
lines.push(message);
|
|
255
|
+
return {
|
|
256
|
+
code: verifyResult.code === 0 ? 1 : verifyResult.code,
|
|
257
|
+
message,
|
|
258
|
+
path: SESSION_READY_FAILED,
|
|
259
|
+
lines,
|
|
260
|
+
steps,
|
|
261
|
+
duration_ms: elapsedMs(started),
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=session-ready.js.map
|
|
@@ -2,15 +2,33 @@ import { type EnvironmentContext } from "../platform/shell-context.js";
|
|
|
2
2
|
import { type ResolveUserMdResult } from "../user-config/resolve-user-md.js";
|
|
3
3
|
import type { GitRunner } from "./git.js";
|
|
4
4
|
import { type ReleaseAvailabilityProbeOptions } from "./release-availability.js";
|
|
5
|
-
import { ritualStatePath } from "./ritual-sentinel.js";
|
|
5
|
+
import { type RitualState, ritualStatePath } from "./ritual-sentinel.js";
|
|
6
6
|
export declare const SESSION_POSTURES: readonly ["read-only", "mutation"];
|
|
7
7
|
export type SessionPosture = (typeof SESSION_POSTURES)[number];
|
|
8
8
|
export declare const READ_ONLY_POSTURE: SessionPosture;
|
|
9
9
|
export declare const MUTATION_POSTURE: SessionPosture;
|
|
10
10
|
export declare const READ_ONLY_ALIGNMENT_MESSAGE = "Deft Directive active -- AGENTS.md loaded.";
|
|
11
11
|
export declare const READ_ONLY_RESULT_MESSAGE = "read-only session posture (alignment only; no ritual-state write)";
|
|
12
|
+
/** Cold (full) vs re-arm (clock/HEAD refresh) ceremony tiers (#2992). */
|
|
13
|
+
export declare const SESSION_CEREMONY_TIERS: readonly ["cold", "rearm"];
|
|
14
|
+
export type SessionCeremonyTier = (typeof SESSION_CEREMONY_TIERS)[number];
|
|
15
|
+
export declare const COLD_CEREMONY_TIER: SessionCeremonyTier;
|
|
16
|
+
export declare const REARM_CEREMONY_TIER: SessionCeremonyTier;
|
|
12
17
|
export declare const QUICK_STEPS: readonly ["alignment", "branch_policy", "triage_welcome"];
|
|
13
18
|
export declare const GATED_STEPS: readonly ["doctor", "cache_fresh"];
|
|
19
|
+
/** Env opt-in for optional session:start network (release probe + triage cache hydrate) (#2991). */
|
|
20
|
+
export declare const ENV_SESSION_START_NETWORK = "DEFT_SESSION_START_NETWORK";
|
|
21
|
+
/** Human-readable skip notice when optional network is off the hot path (#2991). */
|
|
22
|
+
export declare const OPTIONAL_NETWORK_SKIPPED_MESSAGE: string;
|
|
23
|
+
/** Re-arm skips fat cold-path work when prior ritual is still structurally valid (#2992). */
|
|
24
|
+
export declare const REARM_SKIPPED_FAT_PATH_MESSAGE: string;
|
|
25
|
+
/** When --rearm is requested but state requires a full cold ceremony (#2992). */
|
|
26
|
+
export declare const REARM_INELIGIBLE_PREFIX = "session re-arm refused \u2014 full cold session:start required:";
|
|
27
|
+
export interface SessionStartStepTiming {
|
|
28
|
+
readonly name: string;
|
|
29
|
+
readonly duration_ms: number;
|
|
30
|
+
readonly skipped?: boolean;
|
|
31
|
+
}
|
|
14
32
|
export interface DefaultBranchSync {
|
|
15
33
|
readonly branch: string | null;
|
|
16
34
|
readonly upstream: string | null;
|
|
@@ -26,6 +44,12 @@ export interface SessionStartResult {
|
|
|
26
44
|
export interface SessionStartOptions {
|
|
27
45
|
/** #2176: read-only records alignment only; mutation runs the full quick tier. */
|
|
28
46
|
readonly posture?: SessionPosture;
|
|
47
|
+
/**
|
|
48
|
+
* #2992: `rearm` refreshes ritual clock/HEAD/worktree without fat cold path
|
|
49
|
+
* (no verify:tools, triage welcome, release probe, tickler). Default `cold`.
|
|
50
|
+
* CLI: `--rearm` or `--tier=rearm`.
|
|
51
|
+
*/
|
|
52
|
+
readonly ceremonyTier?: SessionCeremonyTier;
|
|
29
53
|
readonly deferrals?: Readonly<Record<string, string>>;
|
|
30
54
|
readonly now?: Date;
|
|
31
55
|
readonly writeHistory?: boolean;
|
|
@@ -52,7 +76,38 @@ export interface SessionStartOptions {
|
|
|
52
76
|
lines: readonly string[];
|
|
53
77
|
prompted: boolean;
|
|
54
78
|
};
|
|
79
|
+
/**
|
|
80
|
+
* #2991: when true, run optional network (npm release probe + triage cache
|
|
81
|
+
* empty-hydrate / self-heal) before ritual-state write. Default false so the
|
|
82
|
+
* mutation hot path does not block on GitHub/npm. CLI: `--with-network`;
|
|
83
|
+
* env: `DEFT_SESSION_START_NETWORK=1`.
|
|
84
|
+
* Ignored on re-arm tier (always skips optional network).
|
|
85
|
+
*/
|
|
86
|
+
readonly allowOptionalNetwork?: boolean;
|
|
87
|
+
/** Process env for network opt-in resolution (tests inject). */
|
|
88
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
55
89
|
}
|
|
90
|
+
/** Format preferred `session:start` recovery command for cold vs re-arm (#2992). */
|
|
91
|
+
export declare function formatSessionStartRecoveryCommand(tier?: SessionCeremonyTier): string;
|
|
92
|
+
export type RearmEligibility = {
|
|
93
|
+
eligible: true;
|
|
94
|
+
state: RitualState;
|
|
95
|
+
currentHead: string;
|
|
96
|
+
currentWorktree: string;
|
|
97
|
+
} | {
|
|
98
|
+
eligible: false;
|
|
99
|
+
reason: string;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Whether a prior ritual can be re-armed without a full cold ceremony (#2992).
|
|
103
|
+
* Requires valid state, same worktree, continuous (or identical) HEAD, and
|
|
104
|
+
* previously-passing quick steps.
|
|
105
|
+
*/
|
|
106
|
+
export declare function assessRearmEligibility(projectRoot: string, options?: {
|
|
107
|
+
runGit?: GitRunner;
|
|
108
|
+
}): RearmEligibility;
|
|
109
|
+
/** Resolve whether optional session:start network work is enabled (#2991). */
|
|
110
|
+
export declare function resolveSessionStartOptionalNetwork(options?: Pick<SessionStartOptions, "allowOptionalNetwork" | "env">): boolean;
|
|
56
111
|
export declare function parseDeferrals(rawValues: readonly string[]): {
|
|
57
112
|
deferrals: Record<string, string>;
|
|
58
113
|
errors: string[];
|