@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
|
@@ -18,7 +18,7 @@ import { SCOPE_NOT_READY_PROMOTE_THEN_ACTIVATE } from "../scope/transition-hint.
|
|
|
18
18
|
import { appendSoftAgentsRebindToMessage, decisionCarriesSoftAgentsRebind, formatSoftAgentsRebindChecklist, } from "../session/compact-ritual.js";
|
|
19
19
|
import { defaultGitRunner, detectBranch, existingAncestorDir, gitCommonDir, memoizeGitRunner, worktreePathOrNull, } from "../session/git.js";
|
|
20
20
|
import { isLinkedWorktreePath } from "../session/main-worktree.js";
|
|
21
|
-
import { evaluateOccupancyWriteGate, formatOccupancyLeaseViewNote, occupancyPath, resolveOccupancyLeaseRoot, } from "../session/occupancy.js";
|
|
21
|
+
import { evaluateApplyingHostLifecycleAdmission, evaluateOccupancyWriteGate, formatOccupancyLeaseViewNote, liveOccupant, occupancyPath, publishApplyingHost, publishApplyingHostFromCanonicalSessionId, resolveOccupancyLeaseRoot, } from "../session/occupancy.js";
|
|
22
22
|
import { occupancyAwareDenialMessage } from "../session/occupancy-recovery.js";
|
|
23
23
|
import { ENV_SESSION_POSTURE, isRequirementsPosture, overlayTrustedSessionPosture, parseSessionPostureToken, REQUIREMENTS_DEFAULT_ALLOW_PATHS, REQUIREMENTS_DEFAULT_DENY_PATHS, REQUIREMENTS_UPGRADE_PATH, } from "../session/posture.js";
|
|
24
24
|
import { emitSessionRitualBlockedProcessCost } from "../session/process-cost.js";
|
|
@@ -2210,6 +2210,48 @@ function remapProxyShellUpdatedInput(outerPayload, outerToolName, shellProxyUnwr
|
|
|
2210
2210
|
// (#5366 Greptile P1). nextToolInput keeps the inner tool name + rewritten command.
|
|
2211
2211
|
return { ...decision, updatedInput: nextToolInput };
|
|
2212
2212
|
}
|
|
2213
|
+
/**
|
|
2214
|
+
* Publish the worktree applying-host record from SessionStart (#5676).
|
|
2215
|
+
*
|
|
2216
|
+
* Best-effort and non-blocking: a publish miss must not deny SessionStart.
|
|
2217
|
+
* Leftover GROK_SESSION_ID alone never selects provider; only GROK_HOOK_EVENT
|
|
2218
|
+
* marks Claude→grok vendor-compat transport.
|
|
2219
|
+
*/
|
|
2220
|
+
function tryPublishApplyingHostFromSessionStart(input, projectRoot) {
|
|
2221
|
+
try {
|
|
2222
|
+
const environ = input.environ ?? process.env;
|
|
2223
|
+
const identity = resolveHookHostIdentity(input.host, input.payload, environ);
|
|
2224
|
+
if (identity.status !== "ok" || identity.sessionId === null)
|
|
2225
|
+
return;
|
|
2226
|
+
// Do not replace applying-host while another session holds the live occupancy
|
|
2227
|
+
// lease — keeps the incumbent owner's heartbeat/release/session:end usable
|
|
2228
|
+
// (#5676 Greptile P1). Matching owner may republish as reinforcement.
|
|
2229
|
+
const live = liveOccupant(projectRoot);
|
|
2230
|
+
if (live !== null && live.sessionId !== identity.sessionId) {
|
|
2231
|
+
return;
|
|
2232
|
+
}
|
|
2233
|
+
const transport = identity.provider === "grok" && environ.GROK_HOOK_EVENT?.trim()
|
|
2234
|
+
? "grok-hook-event"
|
|
2235
|
+
: "native";
|
|
2236
|
+
// Native Cursor SessionStart must stay cursor even when GROK_SESSION_ID lingers.
|
|
2237
|
+
if (input.host === "cursor" && transport === "native") {
|
|
2238
|
+
publishApplyingHost(projectRoot, {
|
|
2239
|
+
provider: "cursor",
|
|
2240
|
+
rawSessionId: identity.rawSessionId,
|
|
2241
|
+
transport: "native",
|
|
2242
|
+
});
|
|
2243
|
+
return;
|
|
2244
|
+
}
|
|
2245
|
+
publishApplyingHost(projectRoot, {
|
|
2246
|
+
provider: identity.provider,
|
|
2247
|
+
rawSessionId: identity.rawSessionId,
|
|
2248
|
+
transport,
|
|
2249
|
+
});
|
|
2250
|
+
}
|
|
2251
|
+
catch {
|
|
2252
|
+
/* SessionStart stays non-blocking */
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2213
2255
|
/**
|
|
2214
2256
|
* Add the claim-time owner only after the existing shell decision allowed the
|
|
2215
2257
|
* command. The host wire format must emit `allow` with updated input, so this
|
|
@@ -2243,6 +2285,21 @@ function attachLifecycleIdentityRewrite(input, toolName, decision, seams) {
|
|
|
2243
2285
|
identity.status === "ok" &&
|
|
2244
2286
|
identity.sessionId !== null &&
|
|
2245
2287
|
hintedSession.sessionId !== identity.sessionId) {
|
|
2288
|
+
const admission = evaluateApplyingHostLifecycleAdmission({
|
|
2289
|
+
projectRoot: resolve(input.projectRoot),
|
|
2290
|
+
// Resolved provider (e.g. Claude+GROK_HOOK_EVENT → grok), not wire host.
|
|
2291
|
+
depositHost: identity.provider,
|
|
2292
|
+
depositSessionId: identity.sessionId,
|
|
2293
|
+
namedSessionId: hintedSession.sessionId,
|
|
2294
|
+
});
|
|
2295
|
+
if (admission.kind === "soft-pass")
|
|
2296
|
+
return decision;
|
|
2297
|
+
if (admission.kind === "repair") {
|
|
2298
|
+
return deny(input, "occupancy-identity-conflict", toolName, withHookHostArgv(input.host, admission.message));
|
|
2299
|
+
}
|
|
2300
|
+
if (admission.kind === "foreign-owner") {
|
|
2301
|
+
return deny(input, "occupancy-identity-conflict", toolName, withHookHostArgv(input.host, admission.message));
|
|
2302
|
+
}
|
|
2246
2303
|
return deny(input, "occupancy-identity-conflict", toolName, `Directive denied ${toolName}: lifecycle command ${hinted} names ` +
|
|
2247
2304
|
`${hintedSession.sessionId ?? "<missing>"}, but the host owner is ` +
|
|
2248
2305
|
`${identity.sessionId}. Re-run as a simple command or pass ` +
|
|
@@ -2254,9 +2311,49 @@ function attachLifecycleIdentityRewrite(input, toolName, decision, seams) {
|
|
|
2254
2311
|
}
|
|
2255
2312
|
return deny(input, "occupancy-identity-unavailable", toolName, uninspectableLifecycleDenyMessage(hinted, named, input.payload));
|
|
2256
2313
|
}
|
|
2257
|
-
// #4660: non-claiming read-only session:start keeps the prior allow
|
|
2258
|
-
|
|
2314
|
+
// #4660: non-claiming read-only session:start keeps the prior allow, and may
|
|
2315
|
+
// publish/repair the applying-host record without requiring a prior record (#5676).
|
|
2316
|
+
// Skip when --project-root (rewriteUnsafe) is present so this hook does not
|
|
2317
|
+
// overwrite a different worktree; the CLI publishes the command target.
|
|
2318
|
+
if (!lifecycle.requiresOwner) {
|
|
2319
|
+
if (lifecycle.rewriteSafe &&
|
|
2320
|
+
lifecycle.sessionIdStatus === "present" &&
|
|
2321
|
+
lifecycle.sessionId !== null) {
|
|
2322
|
+
try {
|
|
2323
|
+
const root = resolve(input.projectRoot);
|
|
2324
|
+
// Same live-lease guard as SessionStart (#5676 Greptile P1): read-only
|
|
2325
|
+
// session:start must not replace applying-host for a foreign live owner.
|
|
2326
|
+
const live = liveOccupant(root);
|
|
2327
|
+
if (live === null || live.sessionId === lifecycle.sessionId) {
|
|
2328
|
+
const environ = input.environ ?? process.env;
|
|
2329
|
+
const transport = environ.GROK_HOOK_EVENT?.trim()
|
|
2330
|
+
? "grok-hook-event"
|
|
2331
|
+
: "native";
|
|
2332
|
+
// Prefer deposit identity when it matches the named canonical owner.
|
|
2333
|
+
const identity = resolveHookHostIdentity(input.host, input.payload, environ);
|
|
2334
|
+
if (identity.status === "ok" &&
|
|
2335
|
+
identity.sessionId === lifecycle.sessionId &&
|
|
2336
|
+
// Leftover GROK_SESSION_ID alone must not publish Cursor as Claude/grok.
|
|
2337
|
+
!(input.host === "cursor" && transport === "grok-hook-event")) {
|
|
2338
|
+
publishApplyingHost(root, {
|
|
2339
|
+
provider: identity.provider,
|
|
2340
|
+
rawSessionId: identity.rawSessionId,
|
|
2341
|
+
transport: input.host === "cursor" ? "native" : transport,
|
|
2342
|
+
});
|
|
2343
|
+
}
|
|
2344
|
+
else {
|
|
2345
|
+
publishApplyingHostFromCanonicalSessionId(root, lifecycle.sessionId, {
|
|
2346
|
+
transport: input.host === "cursor" ? "native" : transport,
|
|
2347
|
+
});
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
catch {
|
|
2352
|
+
/* read-only path stays non-blocking */
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2259
2355
|
return decision;
|
|
2356
|
+
}
|
|
2260
2357
|
const denyIdentity = (code, detail) => deny(input, code, toolName, withHookHostArgv(input.host, detail));
|
|
2261
2358
|
if (lifecycle.sessionIdStatus === "invalid") {
|
|
2262
2359
|
return denyIdentity("occupancy-identity-conflict", `Directive denied exact lifecycle command ${lifecycle.verb}: ` +
|
|
@@ -2279,26 +2376,63 @@ function attachLifecycleIdentityRewrite(input, toolName, decision, seams) {
|
|
|
2279
2376
|
"Directive cannot bind the occupancy claim without a stable host owner; " +
|
|
2280
2377
|
"manual callers must pass --session-id explicitly outside the host rewrite path.");
|
|
2281
2378
|
}
|
|
2379
|
+
const applyingAdmission = evaluateApplyingHostLifecycleAdmission({
|
|
2380
|
+
projectRoot: resolve(input.projectRoot),
|
|
2381
|
+
// Resolved provider (e.g. Claude+GROK_HOOK_EVENT → grok), not wire host.
|
|
2382
|
+
depositHost: identity.provider,
|
|
2383
|
+
depositSessionId: identity.sessionId,
|
|
2384
|
+
namedSessionId: lifecycle.sessionIdStatus === "present" ? (lifecycle.sessionId ?? null) : null,
|
|
2385
|
+
});
|
|
2386
|
+
// Confirmed occupancy:steal must reach stealOccupancy under the thief's
|
|
2387
|
+
// verified identity; applying-host still naming the incumbent must not block
|
|
2388
|
+
// that supported takeover (#5676 Greptile P1).
|
|
2389
|
+
const stealConfirmBypass = lifecycle.verb === "occupancy:steal" &&
|
|
2390
|
+
(hookShellCommand(input.payload) ?? "").split(/\s+/).includes("--confirm");
|
|
2391
|
+
if (applyingAdmission.kind === "repair" && !stealConfirmBypass) {
|
|
2392
|
+
return denyIdentity("occupancy-identity-conflict", applyingAdmission.message);
|
|
2393
|
+
}
|
|
2394
|
+
let liveOwnerBypass = false;
|
|
2395
|
+
if (applyingAdmission.kind === "foreign-owner") {
|
|
2396
|
+
const live = liveOccupant(resolve(input.projectRoot));
|
|
2397
|
+
if (live !== null && live.sessionId === identity.sessionId) {
|
|
2398
|
+
// Applying-host was replaced by another SessionStart; keep live lease owner
|
|
2399
|
+
// on the rewrite path for heartbeat/release/session:end (#5676).
|
|
2400
|
+
liveOwnerBypass = true;
|
|
2401
|
+
}
|
|
2402
|
+
else if (!stealConfirmBypass) {
|
|
2403
|
+
return denyIdentity("occupancy-identity-conflict", applyingAdmission.message);
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
// Confirmed steal: thief is always the verified host identity. Never promote
|
|
2407
|
+
// applying-host (incumbent) or an unrelated --session-id into the lease
|
|
2408
|
+
// (#5676 Greptile P1 "Takeovers trust the wrong owner").
|
|
2409
|
+
const effectiveOwner = stealConfirmBypass || liveOwnerBypass
|
|
2410
|
+
? identity.sessionId
|
|
2411
|
+
: applyingAdmission.kind === "soft-pass" || applyingAdmission.kind === "enforce"
|
|
2412
|
+
? applyingAdmission.record.applyingHostSessionId
|
|
2413
|
+
: identity.sessionId;
|
|
2282
2414
|
const environmentId = (input.environ ?? process.env).DEFT_SESSION_ID?.trim();
|
|
2283
|
-
if (environmentId !== undefined &&
|
|
2284
|
-
|
|
2285
|
-
environmentId !== identity.sessionId) {
|
|
2286
|
-
return denyIdentity("occupancy-identity-conflict", `Directive denied ${toolName}: host owner ${identity.sessionId} conflicts with ` +
|
|
2415
|
+
if (environmentId !== undefined && environmentId.length > 0 && environmentId !== effectiveOwner) {
|
|
2416
|
+
return denyIdentity("occupancy-identity-conflict", `Directive denied ${toolName}: host owner ${effectiveOwner} conflicts with ` +
|
|
2287
2417
|
`DEFT_SESSION_ID ${environmentId}; refusing an auto-approved lifecycle rewrite.`);
|
|
2288
2418
|
}
|
|
2289
|
-
if (lifecycle.sessionIdStatus === "present" && lifecycle.sessionId !==
|
|
2419
|
+
if (lifecycle.sessionIdStatus === "present" && lifecycle.sessionId !== effectiveOwner) {
|
|
2290
2420
|
return denyIdentity("occupancy-identity-conflict", `Directive denied ${toolName}: lifecycle command ${lifecycle.verb} names ` +
|
|
2291
2421
|
`${lifecycle.sessionId ?? "<missing>"}, but the host owner is ` +
|
|
2292
|
-
`${
|
|
2422
|
+
`${effectiveOwner}.`);
|
|
2293
2423
|
}
|
|
2294
2424
|
const sourceTask = !lifecycle.task ||
|
|
2295
2425
|
(seams.runningInsideDeftRepo ?? runningInsideDeftRepo)(resolve(input.projectRoot));
|
|
2296
|
-
const executionRoot = lifecycleExecutionRootCheck(input.payload, input.projectRoot, seams.realpathLifecycleExecutionRoot ?? realpathSync, seams.lifecycleExecutionPlatform ?? process.platform,
|
|
2426
|
+
const executionRoot = lifecycleExecutionRootCheck(input.payload, input.projectRoot, seams.realpathLifecycleExecutionRoot ?? realpathSync, seams.lifecycleExecutionPlatform ?? process.platform, effectiveOwner);
|
|
2297
2427
|
if (!executionRoot.aligned) {
|
|
2298
2428
|
return denyIdentity("occupancy-identity-conflict", `Directive denied exact lifecycle command ${lifecycle.verb}: ${executionRoot.message}. ` +
|
|
2299
2429
|
`Run the lifecycle command from ${normalizeHookProjectRoot(resolve(input.projectRoot))} ` +
|
|
2300
2430
|
"so policy, lease, and ritual state target the same worktree.");
|
|
2301
2431
|
}
|
|
2432
|
+
// Soft-pass still requires same-worktree execution before skipping rewrite (#5676).
|
|
2433
|
+
if (applyingAdmission.kind === "soft-pass") {
|
|
2434
|
+
return decision;
|
|
2435
|
+
}
|
|
2302
2436
|
const rewriteAllowed = lifecycle.rewriteSafe && sourceTask;
|
|
2303
2437
|
if (lifecycle.sessionIdStatus === "absent" && !rewriteAllowed) {
|
|
2304
2438
|
let reason;
|
|
@@ -2309,15 +2443,15 @@ function attachLifecycleIdentityRewrite(input, toolName, decision, seams) {
|
|
|
2309
2443
|
reason = "this argument shape is outside the narrowly auto-approved rewrite surface";
|
|
2310
2444
|
}
|
|
2311
2445
|
return denyIdentity("occupancy-identity-unavailable", `Directive denied exact lifecycle command ${lifecycle.verb}: ${reason}. ` +
|
|
2312
|
-
`Re-run the command with --session-id=${
|
|
2446
|
+
`Re-run the command with --session-id=${effectiveOwner}; Directive will verify ` +
|
|
2313
2447
|
"that explicit owner without auto-approving or replacing the command.");
|
|
2314
2448
|
}
|
|
2315
|
-
const rewrite = rewriteExactLifecycleCommand(input.payload,
|
|
2449
|
+
const rewrite = rewriteExactLifecycleCommand(input.payload, effectiveOwner);
|
|
2316
2450
|
if (rewrite === null)
|
|
2317
2451
|
return decision;
|
|
2318
2452
|
if (rewrite.kind === "conflict") {
|
|
2319
2453
|
return denyIdentity("occupancy-identity-conflict", `Directive denied ${toolName}: ${rewrite.message} Host payload owner is ` +
|
|
2320
|
-
`${
|
|
2454
|
+
`${effectiveOwner}, but the command names ${rewrite.existingSessionId}.`);
|
|
2321
2455
|
}
|
|
2322
2456
|
return { ...decision, updatedInput: rewrite.updatedInput };
|
|
2323
2457
|
}
|
|
@@ -2612,6 +2746,10 @@ function routeHookDecision(input, seams, observation) {
|
|
|
2612
2746
|
scopePath: null,
|
|
2613
2747
|
};
|
|
2614
2748
|
}
|
|
2749
|
+
// #5676: SessionStart-first applying-host record before any Shell PreToolUse.
|
|
2750
|
+
// Leftover GROK_SESSION_ID alone must not remap native Cursor; GROK_HOOK_EVENT
|
|
2751
|
+
// still marks Claude→grok vendor-compat transport.
|
|
2752
|
+
tryPublishApplyingHostFromSessionStart(input, projectRoot);
|
|
2615
2753
|
try {
|
|
2616
2754
|
const result = (seams.sessionStart ?? runSessionStartHookWrite)(projectRoot);
|
|
2617
2755
|
if (result.code !== 0) {
|