@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.
Files changed (153) hide show
  1. package/UPGRADING.md +4 -3
  2. package/commands.md +9 -6
  3. package/contracts/design-critique.md +39 -1
  4. package/dist/doctor-diagnose.d.ts +1 -1
  5. package/dist/doctor-diagnose.js +29 -3
  6. package/dist/doctor.js +1 -1
  7. package/dist/session-start.js +28 -1
  8. package/dist/verify-review-monitor.d.ts +7 -0
  9. package/dist/verify-review-monitor.js +21 -0
  10. package/docs/getting-started.md +13 -1
  11. package/package.json +1 -1
  12. package/packs/skills/skills-pack-0.1.json +4 -4
  13. package/packs/strategies/strategies-pack-0.1.json +32 -19
  14. package/skills/deft-directive-article-review/SKILL.md +104 -24
  15. package/skills/deft-directive-design-critique/SKILL.md +10 -9
  16. package/skills/deft-directive-feedback/SKILL.md +20 -9
  17. package/skills/deft-directive-pre-pr/SKILL.md +14 -0
  18. package/skills/deft-directive-review-cycle/SKILL.md +18 -1
  19. package/skills/deft-directive-setup/SKILL.md +41 -11
  20. package/skills/deft-directive-swarm/references/host-grok-build.md +1 -1
  21. package/skills/deft-directive-tutorial/SKILL.md +1 -1
  22. package/strategies/README.md +1 -0
  23. package/strategies/artifact-guards.md +2 -2
  24. package/strategies/design-thinking.md +182 -0
  25. package/strategies/discuss.md +2 -0
  26. package/strategies/interview.md +76 -23
  27. package/strategies/rapid.md +22 -12
  28. package/templates/agents-entry.md +4 -3
  29. package/templates/design-critique-brief.md +5 -1
  30. package/tutorial/beats.json +2 -2
  31. package/vendor/directive-content/UPGRADING.md +4 -3
  32. package/vendor/directive-content/commands.md +9 -6
  33. package/vendor/directive-content/contracts/design-critique.md +39 -1
  34. package/vendor/directive-content/docs/getting-started.md +13 -1
  35. package/vendor/directive-content/packs/skills/skills-pack-0.1.json +4 -4
  36. package/vendor/directive-content/packs/strategies/strategies-pack-0.1.json +32 -19
  37. package/vendor/directive-content/skills/deft-directive-article-review/SKILL.md +104 -24
  38. package/vendor/directive-content/skills/deft-directive-design-critique/SKILL.md +10 -9
  39. package/vendor/directive-content/skills/deft-directive-feedback/SKILL.md +20 -9
  40. package/vendor/directive-content/skills/deft-directive-pre-pr/SKILL.md +14 -0
  41. package/vendor/directive-content/skills/deft-directive-review-cycle/SKILL.md +18 -1
  42. package/vendor/directive-content/skills/deft-directive-setup/SKILL.md +41 -11
  43. package/vendor/directive-content/skills/deft-directive-swarm/references/host-grok-build.md +1 -1
  44. package/vendor/directive-content/skills/deft-directive-tutorial/SKILL.md +1 -1
  45. package/vendor/directive-content/strategies/README.md +1 -0
  46. package/vendor/directive-content/strategies/artifact-guards.md +2 -2
  47. package/vendor/directive-content/strategies/design-thinking.md +182 -0
  48. package/vendor/directive-content/strategies/discuss.md +2 -0
  49. package/vendor/directive-content/strategies/interview.md +76 -23
  50. package/vendor/directive-content/strategies/rapid.md +22 -12
  51. package/vendor/directive-content/templates/agents-entry.md +4 -3
  52. package/vendor/directive-content/templates/design-critique-brief.md +5 -1
  53. package/vendor/directive-content/tutorial/beats.json +2 -2
  54. package/vendor/directive-core/dist/.tsbuildinfo +1 -1
  55. package/vendor/directive-core/dist/content-contracts/skills/helpers.d.ts +11 -1
  56. package/vendor/directive-core/dist/content-contracts/skills/helpers.d.ts.map +1 -1
  57. package/vendor/directive-core/dist/content-contracts/skills/helpers.js +18 -5
  58. package/vendor/directive-core/dist/content-contracts/skills/helpers.js.map +1 -1
  59. package/vendor/directive-core/dist/design-critique/auto-stamp-path1.d.ts +40 -0
  60. package/vendor/directive-core/dist/design-critique/auto-stamp-path1.d.ts.map +1 -1
  61. package/vendor/directive-core/dist/design-critique/auto-stamp-path1.js +116 -0
  62. package/vendor/directive-core/dist/design-critique/auto-stamp-path1.js.map +1 -1
  63. package/vendor/directive-core/dist/design-critique/citation-grammar.d.ts +36 -0
  64. package/vendor/directive-core/dist/design-critique/citation-grammar.d.ts.map +1 -1
  65. package/vendor/directive-core/dist/design-critique/citation-grammar.js +60 -3
  66. package/vendor/directive-core/dist/design-critique/citation-grammar.js.map +1 -1
  67. package/vendor/directive-core/dist/design-critique/completed-arc-record.d.ts +103 -3
  68. package/vendor/directive-core/dist/design-critique/completed-arc-record.d.ts.map +1 -1
  69. package/vendor/directive-core/dist/design-critique/completed-arc-record.js +127 -5
  70. package/vendor/directive-core/dist/design-critique/completed-arc-record.js.map +1 -1
  71. package/vendor/directive-core/dist/design-critique/ingest-posture.d.ts +27 -0
  72. package/vendor/directive-core/dist/design-critique/ingest-posture.d.ts.map +1 -0
  73. package/vendor/directive-core/dist/design-critique/ingest-posture.js +66 -0
  74. package/vendor/directive-core/dist/design-critique/ingest-posture.js.map +1 -0
  75. package/vendor/directive-core/dist/design-critique/panel-handback-acceptance.d.ts +106 -7
  76. package/vendor/directive-core/dist/design-critique/panel-handback-acceptance.d.ts.map +1 -1
  77. package/vendor/directive-core/dist/design-critique/panel-handback-acceptance.js +284 -17
  78. package/vendor/directive-core/dist/design-critique/panel-handback-acceptance.js.map +1 -1
  79. package/vendor/directive-core/dist/docs/docs-impact.d.ts +13 -0
  80. package/vendor/directive-core/dist/docs/docs-impact.d.ts.map +1 -1
  81. package/vendor/directive-core/dist/docs/docs-impact.js +49 -4
  82. package/vendor/directive-core/dist/docs/docs-impact.js.map +1 -1
  83. package/vendor/directive-core/dist/doctor/main.d.ts +48 -0
  84. package/vendor/directive-core/dist/doctor/main.d.ts.map +1 -1
  85. package/vendor/directive-core/dist/doctor/main.js +221 -4
  86. package/vendor/directive-core/dist/doctor/main.js.map +1 -1
  87. package/vendor/directive-core/dist/hooks/dispatcher.d.ts.map +1 -1
  88. package/vendor/directive-core/dist/hooks/dispatcher.js +151 -13
  89. package/vendor/directive-core/dist/hooks/dispatcher.js.map +1 -1
  90. package/vendor/directive-core/dist/init-deposit/agent-hooks.d.ts +4 -0
  91. package/vendor/directive-core/dist/init-deposit/agent-hooks.d.ts.map +1 -1
  92. package/vendor/directive-core/dist/init-deposit/agent-hooks.js +25 -4
  93. package/vendor/directive-core/dist/init-deposit/agent-hooks.js.map +1 -1
  94. package/vendor/directive-core/dist/intake/issue-ingest.d.ts +2 -0
  95. package/vendor/directive-core/dist/intake/issue-ingest.d.ts.map +1 -1
  96. package/vendor/directive-core/dist/intake/issue-ingest.js +26 -1
  97. package/vendor/directive-core/dist/intake/issue-ingest.js.map +1 -1
  98. package/vendor/directive-core/dist/pr-closing-keywords/detect.d.ts.map +1 -1
  99. package/vendor/directive-core/dist/pr-closing-keywords/detect.js +52 -7
  100. package/vendor/directive-core/dist/pr-closing-keywords/detect.js.map +1 -1
  101. package/vendor/directive-core/dist/pr-watch/main.d.ts +5 -0
  102. package/vendor/directive-core/dist/pr-watch/main.d.ts.map +1 -1
  103. package/vendor/directive-core/dist/pr-watch/main.js.map +1 -1
  104. package/vendor/directive-core/dist/pr-watch/watch.d.ts.map +1 -1
  105. package/vendor/directive-core/dist/pr-watch/watch.js +5 -0
  106. package/vendor/directive-core/dist/pr-watch/watch.js.map +1 -1
  107. package/vendor/directive-core/dist/presentation-ceiling/evaluate.d.ts.map +1 -1
  108. package/vendor/directive-core/dist/presentation-ceiling/evaluate.js +3 -1
  109. package/vendor/directive-core/dist/presentation-ceiling/evaluate.js.map +1 -1
  110. package/vendor/directive-core/dist/release/auto-hatch.d.ts +6 -0
  111. package/vendor/directive-core/dist/release/auto-hatch.d.ts.map +1 -1
  112. package/vendor/directive-core/dist/release/auto-hatch.js +13 -4
  113. package/vendor/directive-core/dist/release/auto-hatch.js.map +1 -1
  114. package/vendor/directive-core/dist/review-monitor/record.d.ts +11 -0
  115. package/vendor/directive-core/dist/review-monitor/record.d.ts.map +1 -1
  116. package/vendor/directive-core/dist/review-monitor/record.js +23 -0
  117. package/vendor/directive-core/dist/review-monitor/record.js.map +1 -1
  118. package/vendor/directive-core/dist/run-summary/emit.d.ts +2 -1
  119. package/vendor/directive-core/dist/run-summary/emit.d.ts.map +1 -1
  120. package/vendor/directive-core/dist/run-summary/emit.js +3 -0
  121. package/vendor/directive-core/dist/run-summary/emit.js.map +1 -1
  122. package/vendor/directive-core/dist/run-summary/index.d.ts +1 -1
  123. package/vendor/directive-core/dist/run-summary/index.d.ts.map +1 -1
  124. package/vendor/directive-core/dist/run-summary/index.js.map +1 -1
  125. package/vendor/directive-core/dist/run-summary/types.d.ts +8 -2
  126. package/vendor/directive-core/dist/run-summary/types.d.ts.map +1 -1
  127. package/vendor/directive-core/dist/run-summary/types.js +1 -0
  128. package/vendor/directive-core/dist/run-summary/types.js.map +1 -1
  129. package/vendor/directive-core/dist/scope/delivery-evidence.d.ts +11 -0
  130. package/vendor/directive-core/dist/scope/delivery-evidence.d.ts.map +1 -1
  131. package/vendor/directive-core/dist/scope/delivery-evidence.js +34 -0
  132. package/vendor/directive-core/dist/scope/delivery-evidence.js.map +1 -1
  133. package/vendor/directive-core/dist/session/occupancy.d.ts +101 -0
  134. package/vendor/directive-core/dist/session/occupancy.d.ts.map +1 -1
  135. package/vendor/directive-core/dist/session/occupancy.js +276 -1
  136. package/vendor/directive-core/dist/session/occupancy.js.map +1 -1
  137. package/vendor/directive-core/dist/swarm/cohort-review-monitors-cli.d.ts.map +1 -1
  138. package/vendor/directive-core/dist/swarm/cohort-review-monitors-cli.js +5 -1
  139. package/vendor/directive-core/dist/swarm/cohort-review-monitors-cli.js.map +1 -1
  140. package/vendor/directive-core/dist/swarm/cohort-review-monitors.d.ts +71 -0
  141. package/vendor/directive-core/dist/swarm/cohort-review-monitors.d.ts.map +1 -1
  142. package/vendor/directive-core/dist/swarm/cohort-review-monitors.js +125 -2
  143. package/vendor/directive-core/dist/swarm/cohort-review-monitors.js.map +1 -1
  144. package/vendor/directive-core/dist/telemetry-coverage/fake-trial.d.ts.map +1 -1
  145. package/vendor/directive-core/dist/telemetry-coverage/fake-trial.js +9 -0
  146. package/vendor/directive-core/dist/telemetry-coverage/fake-trial.js.map +1 -1
  147. package/vendor/directive-core/dist/telemetry-coverage/kinds.d.ts.map +1 -1
  148. package/vendor/directive-core/dist/telemetry-coverage/kinds.js +2 -0
  149. package/vendor/directive-core/dist/telemetry-coverage/kinds.js.map +1 -1
  150. package/vendor/directive-core/dist/value/feedback-file.d.ts +49 -6
  151. package/vendor/directive-core/dist/value/feedback-file.d.ts.map +1 -1
  152. package/vendor/directive-core/dist/value/feedback-file.js +446 -41
  153. 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
  *