@deftai/directive-runtime 0.126.0-beta.2 → 0.126.0-beta.3
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/UPGRADING.md +4 -3
- package/commands.md +9 -6
- package/contracts/design-critique.md +39 -1
- package/dist/doctor-diagnose.d.ts +1 -1
- package/dist/doctor-diagnose.js +29 -3
- package/dist/doctor.js +1 -1
- package/dist/session-start.js +28 -1
- package/dist/verify-review-monitor.d.ts +7 -0
- package/dist/verify-review-monitor.js +21 -0
- package/docs/getting-started.md +13 -1
- package/package.json +1 -1
- package/packs/skills/skills-pack-0.1.json +4 -4
- package/packs/strategies/strategies-pack-0.1.json +32 -19
- package/skills/deft-directive-article-review/SKILL.md +104 -24
- package/skills/deft-directive-design-critique/SKILL.md +10 -9
- package/skills/deft-directive-feedback/SKILL.md +20 -9
- package/skills/deft-directive-pre-pr/SKILL.md +14 -0
- package/skills/deft-directive-review-cycle/SKILL.md +18 -1
- package/skills/deft-directive-setup/SKILL.md +41 -11
- package/skills/deft-directive-swarm/references/host-grok-build.md +1 -1
- package/skills/deft-directive-tutorial/SKILL.md +1 -1
- package/strategies/README.md +1 -0
- package/strategies/artifact-guards.md +2 -2
- package/strategies/design-thinking.md +182 -0
- package/strategies/discuss.md +2 -0
- package/strategies/interview.md +76 -23
- package/strategies/rapid.md +22 -12
- package/templates/agents-entry.md +4 -3
- package/templates/design-critique-brief.md +5 -1
- package/tutorial/beats.json +2 -2
- package/vendor/directive-content/UPGRADING.md +4 -3
- package/vendor/directive-content/commands.md +9 -6
- package/vendor/directive-content/contracts/design-critique.md +39 -1
- package/vendor/directive-content/docs/getting-started.md +13 -1
- package/vendor/directive-content/packs/skills/skills-pack-0.1.json +4 -4
- package/vendor/directive-content/packs/strategies/strategies-pack-0.1.json +32 -19
- package/vendor/directive-content/skills/deft-directive-article-review/SKILL.md +104 -24
- package/vendor/directive-content/skills/deft-directive-design-critique/SKILL.md +10 -9
- package/vendor/directive-content/skills/deft-directive-feedback/SKILL.md +20 -9
- package/vendor/directive-content/skills/deft-directive-pre-pr/SKILL.md +14 -0
- package/vendor/directive-content/skills/deft-directive-review-cycle/SKILL.md +18 -1
- package/vendor/directive-content/skills/deft-directive-setup/SKILL.md +41 -11
- package/vendor/directive-content/skills/deft-directive-swarm/references/host-grok-build.md +1 -1
- package/vendor/directive-content/skills/deft-directive-tutorial/SKILL.md +1 -1
- package/vendor/directive-content/strategies/README.md +1 -0
- package/vendor/directive-content/strategies/artifact-guards.md +2 -2
- package/vendor/directive-content/strategies/design-thinking.md +182 -0
- package/vendor/directive-content/strategies/discuss.md +2 -0
- package/vendor/directive-content/strategies/interview.md +76 -23
- package/vendor/directive-content/strategies/rapid.md +22 -12
- package/vendor/directive-content/templates/agents-entry.md +4 -3
- package/vendor/directive-content/templates/design-critique-brief.md +5 -1
- package/vendor/directive-content/tutorial/beats.json +2 -2
- package/vendor/directive-core/dist/.tsbuildinfo +1 -1
- package/vendor/directive-core/dist/content-contracts/skills/helpers.d.ts +11 -1
- package/vendor/directive-core/dist/content-contracts/skills/helpers.d.ts.map +1 -1
- package/vendor/directive-core/dist/content-contracts/skills/helpers.js +18 -5
- package/vendor/directive-core/dist/content-contracts/skills/helpers.js.map +1 -1
- package/vendor/directive-core/dist/design-critique/auto-stamp-path1.d.ts +40 -0
- package/vendor/directive-core/dist/design-critique/auto-stamp-path1.d.ts.map +1 -1
- package/vendor/directive-core/dist/design-critique/auto-stamp-path1.js +116 -0
- package/vendor/directive-core/dist/design-critique/auto-stamp-path1.js.map +1 -1
- package/vendor/directive-core/dist/design-critique/citation-grammar.d.ts +36 -0
- package/vendor/directive-core/dist/design-critique/citation-grammar.d.ts.map +1 -1
- package/vendor/directive-core/dist/design-critique/citation-grammar.js +60 -3
- package/vendor/directive-core/dist/design-critique/citation-grammar.js.map +1 -1
- package/vendor/directive-core/dist/design-critique/completed-arc-record.d.ts +103 -3
- package/vendor/directive-core/dist/design-critique/completed-arc-record.d.ts.map +1 -1
- package/vendor/directive-core/dist/design-critique/completed-arc-record.js +127 -5
- package/vendor/directive-core/dist/design-critique/completed-arc-record.js.map +1 -1
- package/vendor/directive-core/dist/design-critique/ingest-posture.d.ts +27 -0
- package/vendor/directive-core/dist/design-critique/ingest-posture.d.ts.map +1 -0
- package/vendor/directive-core/dist/design-critique/ingest-posture.js +66 -0
- package/vendor/directive-core/dist/design-critique/ingest-posture.js.map +1 -0
- package/vendor/directive-core/dist/design-critique/panel-handback-acceptance.d.ts +106 -7
- package/vendor/directive-core/dist/design-critique/panel-handback-acceptance.d.ts.map +1 -1
- package/vendor/directive-core/dist/design-critique/panel-handback-acceptance.js +284 -17
- package/vendor/directive-core/dist/design-critique/panel-handback-acceptance.js.map +1 -1
- package/vendor/directive-core/dist/docs/docs-impact.d.ts +13 -0
- package/vendor/directive-core/dist/docs/docs-impact.d.ts.map +1 -1
- package/vendor/directive-core/dist/docs/docs-impact.js +49 -4
- package/vendor/directive-core/dist/docs/docs-impact.js.map +1 -1
- package/vendor/directive-core/dist/doctor/main.d.ts +48 -0
- package/vendor/directive-core/dist/doctor/main.d.ts.map +1 -1
- package/vendor/directive-core/dist/doctor/main.js +221 -4
- package/vendor/directive-core/dist/doctor/main.js.map +1 -1
- package/vendor/directive-core/dist/hooks/dispatcher.d.ts.map +1 -1
- package/vendor/directive-core/dist/hooks/dispatcher.js +151 -13
- package/vendor/directive-core/dist/hooks/dispatcher.js.map +1 -1
- package/vendor/directive-core/dist/init-deposit/agent-hooks.d.ts +4 -0
- package/vendor/directive-core/dist/init-deposit/agent-hooks.d.ts.map +1 -1
- package/vendor/directive-core/dist/init-deposit/agent-hooks.js +25 -4
- package/vendor/directive-core/dist/init-deposit/agent-hooks.js.map +1 -1
- package/vendor/directive-core/dist/intake/issue-ingest.d.ts +2 -0
- package/vendor/directive-core/dist/intake/issue-ingest.d.ts.map +1 -1
- package/vendor/directive-core/dist/intake/issue-ingest.js +26 -1
- package/vendor/directive-core/dist/intake/issue-ingest.js.map +1 -1
- package/vendor/directive-core/dist/pr-closing-keywords/detect.d.ts.map +1 -1
- package/vendor/directive-core/dist/pr-closing-keywords/detect.js +52 -7
- package/vendor/directive-core/dist/pr-closing-keywords/detect.js.map +1 -1
- package/vendor/directive-core/dist/pr-watch/main.d.ts +5 -0
- package/vendor/directive-core/dist/pr-watch/main.d.ts.map +1 -1
- package/vendor/directive-core/dist/pr-watch/main.js.map +1 -1
- package/vendor/directive-core/dist/pr-watch/watch.d.ts.map +1 -1
- package/vendor/directive-core/dist/pr-watch/watch.js +5 -0
- package/vendor/directive-core/dist/pr-watch/watch.js.map +1 -1
- package/vendor/directive-core/dist/presentation-ceiling/evaluate.d.ts.map +1 -1
- package/vendor/directive-core/dist/presentation-ceiling/evaluate.js +3 -1
- package/vendor/directive-core/dist/presentation-ceiling/evaluate.js.map +1 -1
- package/vendor/directive-core/dist/release/auto-hatch.d.ts +6 -0
- package/vendor/directive-core/dist/release/auto-hatch.d.ts.map +1 -1
- package/vendor/directive-core/dist/release/auto-hatch.js +13 -4
- package/vendor/directive-core/dist/release/auto-hatch.js.map +1 -1
- package/vendor/directive-core/dist/review-monitor/record.d.ts +11 -0
- package/vendor/directive-core/dist/review-monitor/record.d.ts.map +1 -1
- package/vendor/directive-core/dist/review-monitor/record.js +23 -0
- package/vendor/directive-core/dist/review-monitor/record.js.map +1 -1
- package/vendor/directive-core/dist/run-summary/emit.d.ts +2 -1
- package/vendor/directive-core/dist/run-summary/emit.d.ts.map +1 -1
- package/vendor/directive-core/dist/run-summary/emit.js +3 -0
- package/vendor/directive-core/dist/run-summary/emit.js.map +1 -1
- package/vendor/directive-core/dist/run-summary/index.d.ts +1 -1
- package/vendor/directive-core/dist/run-summary/index.d.ts.map +1 -1
- package/vendor/directive-core/dist/run-summary/index.js.map +1 -1
- package/vendor/directive-core/dist/run-summary/types.d.ts +8 -2
- package/vendor/directive-core/dist/run-summary/types.d.ts.map +1 -1
- package/vendor/directive-core/dist/run-summary/types.js +1 -0
- package/vendor/directive-core/dist/run-summary/types.js.map +1 -1
- package/vendor/directive-core/dist/scope/delivery-evidence.d.ts +11 -0
- package/vendor/directive-core/dist/scope/delivery-evidence.d.ts.map +1 -1
- package/vendor/directive-core/dist/scope/delivery-evidence.js +34 -0
- package/vendor/directive-core/dist/scope/delivery-evidence.js.map +1 -1
- package/vendor/directive-core/dist/session/occupancy.d.ts +101 -0
- package/vendor/directive-core/dist/session/occupancy.d.ts.map +1 -1
- package/vendor/directive-core/dist/session/occupancy.js +276 -1
- package/vendor/directive-core/dist/session/occupancy.js.map +1 -1
- package/vendor/directive-core/dist/swarm/cohort-review-monitors-cli.d.ts.map +1 -1
- package/vendor/directive-core/dist/swarm/cohort-review-monitors-cli.js +5 -1
- package/vendor/directive-core/dist/swarm/cohort-review-monitors-cli.js.map +1 -1
- package/vendor/directive-core/dist/swarm/cohort-review-monitors.d.ts +71 -0
- package/vendor/directive-core/dist/swarm/cohort-review-monitors.d.ts.map +1 -1
- package/vendor/directive-core/dist/swarm/cohort-review-monitors.js +125 -2
- package/vendor/directive-core/dist/swarm/cohort-review-monitors.js.map +1 -1
- package/vendor/directive-core/dist/telemetry-coverage/fake-trial.d.ts.map +1 -1
- package/vendor/directive-core/dist/telemetry-coverage/fake-trial.js +9 -0
- package/vendor/directive-core/dist/telemetry-coverage/fake-trial.js.map +1 -1
- package/vendor/directive-core/dist/telemetry-coverage/kinds.d.ts.map +1 -1
- package/vendor/directive-core/dist/telemetry-coverage/kinds.js +2 -0
- package/vendor/directive-core/dist/telemetry-coverage/kinds.js.map +1 -1
- package/vendor/directive-core/dist/value/feedback-file.d.ts +49 -6
- package/vendor/directive-core/dist/value/feedback-file.d.ts.map +1 -1
- package/vendor/directive-core/dist/value/feedback-file.js +446 -41
- package/vendor/directive-core/dist/value/feedback-file.js.map +1 -1
|
@@ -76,7 +76,7 @@ import { assertAppendLockOwned, withAppendLock } from "../slice/lock.js";
|
|
|
76
76
|
import { SWARM_WORKER_ROLES } from "../swarm/routing.js";
|
|
77
77
|
import { recordChildOccupancyLease } from "./child-occupancy.js";
|
|
78
78
|
import { worktreePathOrNull } from "./git.js";
|
|
79
|
-
import { ambientHostSessionOwner, claimsHostSessionIdShape, detectDeclaredIdentityHosts, isUsableHostSessionId, parseCanonicalHostSessionId, printCompanionHostOwner, } from "./host-session-owner.js";
|
|
79
|
+
import { ambientHostSessionOwner, canonicalHostSessionId, claimsHostSessionIdShape, detectDeclaredIdentityHosts, HOST_IDENTITY_PROVIDERS, isUsableHostSessionId, parseCanonicalHostSessionId, printCompanionHostOwner, } from "./host-session-owner.js";
|
|
80
80
|
import { stableJson } from "./json.js";
|
|
81
81
|
import { isLinkedWorktreePath, isMainWorktreePath, listLinkedWorktreeCheckouts, mainWorktreeRoot, } from "./main-worktree.js";
|
|
82
82
|
import { readRitualState } from "./ritual-sentinel.js";
|
|
@@ -90,6 +90,15 @@ export const OCCUPANCY_RELPATH = [".deft", "occupancy.json"];
|
|
|
90
90
|
* later host can self-claim.
|
|
91
91
|
*/
|
|
92
92
|
export const DEFT_EXPECTED_DECLARED_HOST_ATTACH = "DEFT_EXPECTED_DECLARED_HOST_ATTACH";
|
|
93
|
+
/** Worktree applying-host record for multi-host PreToolUse deposits (#5676). */
|
|
94
|
+
export const APPLYING_HOST_RELPATH = [".deft", "applying-host.json"];
|
|
95
|
+
export const APPLYING_HOST_SCHEMA = "deft.applying-host.v1";
|
|
96
|
+
/**
|
|
97
|
+
* Applying-host staleness floor (#5676). Mirrors tip ritual staleness (8h) so a
|
|
98
|
+
* reconnect SessionStart / read-only session:start republish stays in the same
|
|
99
|
+
* recovery window as ceremony re-arm; UUID residual stays under #5544.
|
|
100
|
+
*/
|
|
101
|
+
export const APPLYING_HOST_STALE_MS = Number("8") * 60 * 60 * 1000;
|
|
93
102
|
/** Crash recovery TTL: 20 minutes without heartbeat (15–30 window). */
|
|
94
103
|
export const OCCUPANCY_TTL_MS = 20 * 60 * 1000;
|
|
95
104
|
/**
|
|
@@ -235,6 +244,272 @@ export const OCCUPANCY_MAX_GRANTS = 32;
|
|
|
235
244
|
export function occupancyPath(projectRoot) {
|
|
236
245
|
return join(resolve(projectRoot), ...OCCUPANCY_RELPATH);
|
|
237
246
|
}
|
|
247
|
+
export function applyingHostPath(projectRoot) {
|
|
248
|
+
return join(resolve(projectRoot), ...APPLYING_HOST_RELPATH);
|
|
249
|
+
}
|
|
250
|
+
function isHookHostIdentityProvider(value) {
|
|
251
|
+
return HOST_IDENTITY_PROVIDERS.includes(value);
|
|
252
|
+
}
|
|
253
|
+
function parseApplyingHostPayload(payload) {
|
|
254
|
+
if (payload === null || typeof payload !== "object" || Array.isArray(payload))
|
|
255
|
+
return null;
|
|
256
|
+
const row = payload;
|
|
257
|
+
if (row.schema !== APPLYING_HOST_SCHEMA)
|
|
258
|
+
return null;
|
|
259
|
+
if (typeof row.provider !== "string" || !isHookHostIdentityProvider(row.provider))
|
|
260
|
+
return null;
|
|
261
|
+
if (typeof row.rawSessionId !== "string" || !isUsableHostSessionId(row.rawSessionId))
|
|
262
|
+
return null;
|
|
263
|
+
if (typeof row.applyingHostSessionId !== "string")
|
|
264
|
+
return null;
|
|
265
|
+
if (typeof row.claimed_at !== "string" || parseTimestamp(row.claimed_at) === null)
|
|
266
|
+
return null;
|
|
267
|
+
const transport = row.transport === "grok-hook-event" ? "grok-hook-event" : "native";
|
|
268
|
+
const expected = canonicalHostSessionId(row.provider, row.rawSessionId);
|
|
269
|
+
if (row.applyingHostSessionId !== expected)
|
|
270
|
+
return null;
|
|
271
|
+
return {
|
|
272
|
+
schema: APPLYING_HOST_SCHEMA,
|
|
273
|
+
provider: row.provider,
|
|
274
|
+
rawSessionId: row.rawSessionId,
|
|
275
|
+
applyingHostSessionId: expected,
|
|
276
|
+
claimed_at: row.claimed_at,
|
|
277
|
+
transport,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
/** Read the worktree applying-host record (#5676). */
|
|
281
|
+
export function readApplyingHost(projectRoot, now = new Date()) {
|
|
282
|
+
const path = applyingHostPath(projectRoot);
|
|
283
|
+
try {
|
|
284
|
+
if (!existsSync(path))
|
|
285
|
+
return { status: "missing", record: null };
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
return { status: "missing", record: null };
|
|
289
|
+
}
|
|
290
|
+
let payload;
|
|
291
|
+
try {
|
|
292
|
+
payload = JSON.parse(readFileSync(path, { encoding: "utf8" }));
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
return {
|
|
296
|
+
status: "invalid",
|
|
297
|
+
record: null,
|
|
298
|
+
message: "applying-host record is unreadable; republish via SessionStart or read-only session:start",
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
const record = parseApplyingHostPayload(payload);
|
|
302
|
+
if (record === null) {
|
|
303
|
+
return {
|
|
304
|
+
status: "invalid",
|
|
305
|
+
record: null,
|
|
306
|
+
message: "applying-host record is malformed; republish via SessionStart or read-only session:start",
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
const claimedAt = parseTimestamp(record.claimed_at);
|
|
310
|
+
if (claimedAt === null) {
|
|
311
|
+
return {
|
|
312
|
+
status: "invalid",
|
|
313
|
+
record: null,
|
|
314
|
+
message: "applying-host record has invalid claimed_at; republish via SessionStart or read-only session:start",
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
if (now.getTime() - claimedAt.getTime() > APPLYING_HOST_STALE_MS) {
|
|
318
|
+
return {
|
|
319
|
+
status: "stale",
|
|
320
|
+
record,
|
|
321
|
+
message: formatApplyingHostRepairDiagnostic("stale"),
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
return { status: "ok", record };
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Supported repair when the applying-host record is missing, stale, or
|
|
328
|
+
* conflicting (#5676 Prefer-A Recut-5). Mutation session:start is reinforcement
|
|
329
|
+
* only — first publication is SessionStart or read-only session:start.
|
|
330
|
+
*/
|
|
331
|
+
export function formatApplyingHostRepairDiagnostic(reason = "missing") {
|
|
332
|
+
const subject = reason === "missing"
|
|
333
|
+
? "Applying-host record is missing"
|
|
334
|
+
: reason === "stale"
|
|
335
|
+
? "Applying-host record is stale"
|
|
336
|
+
: reason === "conflicting"
|
|
337
|
+
? "Applying-host record conflicts with this host session"
|
|
338
|
+
: "Applying-host record is invalid";
|
|
339
|
+
return (`${subject}. Republish via host SessionStart reconnect and/or ` +
|
|
340
|
+
"`deft session:start --read-only --session-id=<applyingHostSessionId>` " +
|
|
341
|
+
"before retrying mutation lifecycle. UUID / Harbor residuals stay under #5544.");
|
|
342
|
+
}
|
|
343
|
+
/** Write/replace the worktree applying-host record (#5676). */
|
|
344
|
+
export function publishApplyingHost(projectRoot, input) {
|
|
345
|
+
if (!isUsableHostSessionId(input.rawSessionId)) {
|
|
346
|
+
throw new Error("publishApplyingHost: rawSessionId is not a usable host session id");
|
|
347
|
+
}
|
|
348
|
+
const root = resolve(projectRoot);
|
|
349
|
+
const claimedAt = input.claimedAt ?? new Date();
|
|
350
|
+
const record = {
|
|
351
|
+
schema: APPLYING_HOST_SCHEMA,
|
|
352
|
+
provider: input.provider,
|
|
353
|
+
rawSessionId: input.rawSessionId,
|
|
354
|
+
applyingHostSessionId: canonicalHostSessionId(input.provider, input.rawSessionId),
|
|
355
|
+
claimed_at: timestampIso(claimedAt),
|
|
356
|
+
transport: input.transport ?? "native",
|
|
357
|
+
};
|
|
358
|
+
const target = applyingHostPath(root);
|
|
359
|
+
assertWriteTargetSafe(root, target);
|
|
360
|
+
const dir = dirname(target);
|
|
361
|
+
const tmpName = join(dir, `.applying-host.${process.pid}.json.tmp`);
|
|
362
|
+
const text = `${stableJson(record, 2)}\n`;
|
|
363
|
+
try {
|
|
364
|
+
containedWrite({ root, target: tmpName, data: text, mode: "create" });
|
|
365
|
+
renameSync(tmpName, target);
|
|
366
|
+
}
|
|
367
|
+
finally {
|
|
368
|
+
try {
|
|
369
|
+
rmSync(tmpName, { force: true });
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
/* best-effort cleanup of tmp only */
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return record;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Publish from a canonical `host:<provider>:v1:<base64url>` owner (#5676).
|
|
379
|
+
* Returns null when the id is not canonical (opaque UUID leftovers stay #5544).
|
|
380
|
+
*/
|
|
381
|
+
export function publishApplyingHostFromCanonicalSessionId(projectRoot, sessionId, opts = {}) {
|
|
382
|
+
const parsed = parseCanonicalHostSessionId(sessionId.trim());
|
|
383
|
+
if (parsed === null)
|
|
384
|
+
return null;
|
|
385
|
+
return publishApplyingHost(projectRoot, {
|
|
386
|
+
provider: parsed.provider,
|
|
387
|
+
rawSessionId: parsed.rawSessionId,
|
|
388
|
+
claimedAt: opts.claimedAt,
|
|
389
|
+
transport: opts.transport,
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Lifecycle admission against the applying-host record (#5676).
|
|
394
|
+
*
|
|
395
|
+
* Matching deposits enforce `applyingHostSessionId`. Non-matching deposits
|
|
396
|
+
* soft-pass only when the command already names that id. Missing/stale/
|
|
397
|
+
* conflicting records name SessionStart / read-only repair. Absent record with
|
|
398
|
+
* no flip-flop shape returns `absent` so single-host flows keep prior behavior.
|
|
399
|
+
*/
|
|
400
|
+
export function evaluateApplyingHostLifecycleAdmission(input) {
|
|
401
|
+
const read = readApplyingHost(input.projectRoot, input.now ?? new Date());
|
|
402
|
+
if (read.status === "invalid") {
|
|
403
|
+
return {
|
|
404
|
+
kind: "repair",
|
|
405
|
+
record: null,
|
|
406
|
+
message: read.message,
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
if (read.status === "stale") {
|
|
410
|
+
// Live occupancy owner cleanup when applying-host TTL elapsed but the lease
|
|
411
|
+
// is still heartbeat-fresh (#5676 Greptile P1). Soft-pass only when argv
|
|
412
|
+
// already names that live owner so bare commands keep the rewrite path.
|
|
413
|
+
const staleLive = liveOccupant(input.projectRoot, input.now ?? new Date());
|
|
414
|
+
const staleLiveId = staleLive?.sessionId ?? null;
|
|
415
|
+
const staleNamed = input.namedSessionId?.trim() || null;
|
|
416
|
+
if (staleLiveId !== null &&
|
|
417
|
+
read.record.applyingHostSessionId === staleLiveId &&
|
|
418
|
+
staleNamed === staleLiveId) {
|
|
419
|
+
return {
|
|
420
|
+
kind: "soft-pass",
|
|
421
|
+
record: read.record,
|
|
422
|
+
reason: "live-lease-owner-cleanup",
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
return { kind: "repair", record: read.record, message: read.message };
|
|
426
|
+
}
|
|
427
|
+
if (read.status === "missing" || read.record === null) {
|
|
428
|
+
const named = input.namedSessionId?.trim() || null;
|
|
429
|
+
const deposit = input.depositSessionId?.trim() || null;
|
|
430
|
+
if (named !== null && deposit !== null && named !== deposit) {
|
|
431
|
+
const namedParts = parseCanonicalHostSessionId(named);
|
|
432
|
+
const depositParts = parseCanonicalHostSessionId(deposit);
|
|
433
|
+
if (namedParts !== null &&
|
|
434
|
+
depositParts !== null &&
|
|
435
|
+
namedParts.rawSessionId === depositParts.rawSessionId &&
|
|
436
|
+
namedParts.provider !== depositParts.provider) {
|
|
437
|
+
return {
|
|
438
|
+
kind: "repair",
|
|
439
|
+
record: null,
|
|
440
|
+
message: formatApplyingHostRepairDiagnostic("missing"),
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return { kind: "absent", record: null };
|
|
445
|
+
}
|
|
446
|
+
const record = read.record;
|
|
447
|
+
// Live occupancy owner cleanup when a later SessionStart replaced applying-host
|
|
448
|
+
// (#5676 Greptile P1). Only soft-pass when argv already names that live owner so
|
|
449
|
+
// bare commands still take the rewrite path (do not skip --session-id injection).
|
|
450
|
+
const live = liveOccupant(input.projectRoot, input.now ?? new Date());
|
|
451
|
+
const liveId = live?.sessionId ?? null;
|
|
452
|
+
const named = input.namedSessionId?.trim() || null;
|
|
453
|
+
if (liveId !== null && record.applyingHostSessionId !== liveId && named === liveId) {
|
|
454
|
+
return {
|
|
455
|
+
kind: "soft-pass",
|
|
456
|
+
record,
|
|
457
|
+
reason: "live-lease-owner-cleanup",
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
if (isHookHostIdentityProvider(input.depositHost) &&
|
|
461
|
+
input.depositHost === record.provider &&
|
|
462
|
+
input.depositSessionId !== null &&
|
|
463
|
+
input.depositSessionId !== record.applyingHostSessionId) {
|
|
464
|
+
const depositParts = parseCanonicalHostSessionId(input.depositSessionId);
|
|
465
|
+
if (depositParts === null || depositParts.rawSessionId !== record.rawSessionId) {
|
|
466
|
+
return {
|
|
467
|
+
kind: "repair",
|
|
468
|
+
record,
|
|
469
|
+
message: formatApplyingHostRepairDiagnostic("conflicting"),
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
const matchingDeposit = input.depositHost === record.provider;
|
|
474
|
+
if (!matchingDeposit) {
|
|
475
|
+
// Soft-pass only when argv already names applyingHostSessionId (#5676).
|
|
476
|
+
// Bare commands must not skip the owner rewrite / explicit-owner gate.
|
|
477
|
+
if (named === record.applyingHostSessionId) {
|
|
478
|
+
return {
|
|
479
|
+
kind: "soft-pass",
|
|
480
|
+
record,
|
|
481
|
+
reason: "non-matching-deposit-names-applying-host",
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
return {
|
|
485
|
+
kind: "foreign-owner",
|
|
486
|
+
record,
|
|
487
|
+
namedSessionId: named,
|
|
488
|
+
message: named === null
|
|
489
|
+
? `Directive refused bare lifecycle command; applying-host is ` +
|
|
490
|
+
`${record.applyingHostSessionId}. Re-run with ` +
|
|
491
|
+
`--session-id=${record.applyingHostSessionId}.`
|
|
492
|
+
: `Directive refused foreign owner ${named}; applying-host is ` +
|
|
493
|
+
`${record.applyingHostSessionId}. Re-run with ` +
|
|
494
|
+
`--session-id=${record.applyingHostSessionId}.`,
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
if (named !== null && named !== record.applyingHostSessionId) {
|
|
498
|
+
return {
|
|
499
|
+
kind: "foreign-owner",
|
|
500
|
+
record,
|
|
501
|
+
namedSessionId: named,
|
|
502
|
+
message: `Directive refused foreign owner ${named}; applying-host is ` +
|
|
503
|
+
`${record.applyingHostSessionId}. Re-run with ` +
|
|
504
|
+
`--session-id=${record.applyingHostSessionId}.`,
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
return {
|
|
508
|
+
kind: "enforce",
|
|
509
|
+
record,
|
|
510
|
+
matchingDeposit: true,
|
|
511
|
+
};
|
|
512
|
+
}
|
|
238
513
|
/**
|
|
239
514
|
* Resolve the lease root CLI and hooks share for the same worktree (#5544 P2).
|
|
240
515
|
*
|