@akagilnc/pi-workflow-roles 0.1.5775 → 0.1.5797
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/acp-host/production-host.js +556 -209
- package/dist/external-host-turn-loop.js +3 -0
- package/dist/headless-host/production-host.js +529 -182
- package/dist/migrate-book-topology.js +63 -23
- package/dist/pi/role-turn-host.js +6 -1
- package/dist/public-cli/instruction-seat-run.js +10 -7
- package/dist/public-cli/invocation.js +95 -39
- package/dist/public-cli/main.js +357 -147
- package/dist/public-cli/post-admission.js +2 -0
- package/dist/public-cli/run-lifecycle.js +10 -4
- package/dist/public-cli/turn-request.js +3 -0
- package/dist/report-ticket-tool.js +3 -3
- package/dist/role-run-placement.js +14 -2
- package/dist/role-run-relocation.js +2 -2
- package/dist/run-dossier.js +5 -4
- package/dist/session-identity.js +3 -2
- package/dist/sitian-appender.js +12 -3
- package/dist/submission-ledger.js +24 -0
- package/dist/ticket-progress.js +306 -0
- package/dist/user-dialogue-stdin.js +23 -17
- package/package.json +1 -1
- package/src/external-host-turn-loop.ts +7 -1
- package/src/host-contracts.ts +1 -1
- package/src/pi/adapter.ts +57 -45
- package/src/pi/role-turn-host.ts +6 -1
- package/src/prepared-role-turn.ts +6 -0
- package/src/public-cli/instruction-seat-run.ts +10 -7
- package/src/public-cli/invocation.ts +116 -38
- package/src/public-cli/post-admission.ts +3 -1
- package/src/public-cli/run-lifecycle.ts +10 -8
- package/src/public-cli/turn-request.ts +3 -0
- package/src/report-ticket-tool.ts +7 -3
- package/src/role-envelope.ts +5 -0
- package/src/role-run-placement.ts +19 -2
- package/src/role-run-relocation.ts +2 -2
- package/src/role-runtime.ts +14 -3
- package/src/run-dossier.ts +5 -3
- package/src/run-terminal-artifacts.ts +0 -1
- package/src/session-identity.ts +3 -2
- package/src/sitian-appender.ts +14 -3
- package/src/submission-ledger.ts +27 -0
- package/src/ticket-progress.ts +383 -0
- package/src/user-dialogue-stdin.ts +21 -14
|
@@ -958,6 +958,12 @@ import { basename as basename3, dirname as dirname3, join as join2 } from "node:
|
|
|
958
958
|
function resolveSitianVolumeCategory(kind) {
|
|
959
959
|
return kind;
|
|
960
960
|
}
|
|
961
|
+
function runDirectoryOwningSessionParent(sessionParentDir) {
|
|
962
|
+
if (basename3(sessionParentDir) !== "session") return void 0;
|
|
963
|
+
const runDirectory = dirname3(sessionParentDir);
|
|
964
|
+
if (parseRunLeaf(basename3(runDirectory)) === void 0) return void 0;
|
|
965
|
+
return runDirectory;
|
|
966
|
+
}
|
|
961
967
|
function sitianVolumeDirectory(sessionDirectory, category) {
|
|
962
968
|
return join2(sessionDirectory, category);
|
|
963
969
|
}
|
|
@@ -989,8 +995,8 @@ function resolveSitianRecordPathInLedger(input, ledgerHome) {
|
|
|
989
995
|
throw new Error("Sitian record ownership requires a parent session inside the ledger home");
|
|
990
996
|
}
|
|
991
997
|
const sessionParentDir = dirname3(input.sessionParent);
|
|
992
|
-
const runDirectory =
|
|
993
|
-
if (
|
|
998
|
+
const runDirectory = runDirectoryOwningSessionParent(sessionParentDir);
|
|
999
|
+
if (runDirectory !== void 0) {
|
|
994
1000
|
sessionDir = runDirectory;
|
|
995
1001
|
recordFile = join2(runDirectory, RUN_HISTORY_KINDS.has(input.kind) ? RUN_HISTORY_FILE : RUN_STATE_KINDS.has(input.kind) ? RUN_STATE_FILE : RUN_LOG_FILE);
|
|
996
1002
|
} else {
|
|
@@ -1183,7 +1189,9 @@ function render(runDirectory, history, state, log, unreadable) {
|
|
|
1183
1189
|
original = payload.landingPath;
|
|
1184
1190
|
}
|
|
1185
1191
|
}
|
|
1186
|
-
if (typeof original === "string")
|
|
1192
|
+
if (typeof original === "string") {
|
|
1193
|
+
original = join3(sessionDirectoryOf(runDirectory), basename4(original));
|
|
1194
|
+
}
|
|
1187
1195
|
whole.host = { sessions, ...original === void 0 ? {} : { original } };
|
|
1188
1196
|
whole.submission = latest === void 0 ? {} : { latest };
|
|
1189
1197
|
if (Object.keys(unreadable).length > 0) whole.unreadable = unreadable;
|
|
@@ -10176,7 +10184,7 @@ async function rewriteSessionTranscriptBindings(path, rewrites) {
|
|
|
10176
10184
|
);
|
|
10177
10185
|
}
|
|
10178
10186
|
async function rewriteNestedMachinePathPages(pagesDirectory, rewrites) {
|
|
10179
|
-
const sessionRoot =
|
|
10187
|
+
const sessionRoot = sessionDirectoryOf(pagesDirectory);
|
|
10180
10188
|
async function walk(directory) {
|
|
10181
10189
|
let entries;
|
|
10182
10190
|
try {
|
|
@@ -10273,13 +10281,30 @@ var init_role_run_relocation = __esm({
|
|
|
10273
10281
|
}
|
|
10274
10282
|
});
|
|
10275
10283
|
|
|
10276
|
-
// src/
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
|
|
10284
|
+
// src/sitian-facade.ts
|
|
10285
|
+
var init_sitian_facade = __esm({
|
|
10286
|
+
"src/sitian-facade.ts"() {
|
|
10287
|
+
"use strict";
|
|
10288
|
+
init_role_run_placement();
|
|
10289
|
+
init_sitian_appender();
|
|
10290
|
+
init_sitian_contracts();
|
|
10291
|
+
init_sitian_appender();
|
|
10292
|
+
init_sitian_reader();
|
|
10293
|
+
}
|
|
10294
|
+
});
|
|
10295
|
+
|
|
10296
|
+
// src/host-session-record.ts
|
|
10297
|
+
var init_host_session_record = __esm({
|
|
10298
|
+
"src/host-session-record.ts"() {
|
|
10299
|
+
"use strict";
|
|
10300
|
+
init_sitian_facade();
|
|
10301
|
+
init_unknown_value();
|
|
10302
|
+
}
|
|
10303
|
+
});
|
|
10304
|
+
|
|
10305
|
+
// src/host-contracts.ts
|
|
10306
|
+
var init_host_contracts = __esm({
|
|
10307
|
+
"src/host-contracts.ts"() {
|
|
10283
10308
|
"use strict";
|
|
10284
10309
|
}
|
|
10285
10310
|
});
|
|
@@ -10328,6 +10353,32 @@ var init_terminating_tools = __esm({
|
|
|
10328
10353
|
}
|
|
10329
10354
|
});
|
|
10330
10355
|
|
|
10356
|
+
// src/ticket-progress.ts
|
|
10357
|
+
var init_ticket_progress = __esm({
|
|
10358
|
+
"src/ticket-progress.ts"() {
|
|
10359
|
+
"use strict";
|
|
10360
|
+
init_host_session_record();
|
|
10361
|
+
init_host_contracts();
|
|
10362
|
+
init_terminating_tools();
|
|
10363
|
+
init_packaged_role_registry();
|
|
10364
|
+
init_role_run_placement();
|
|
10365
|
+
init_run_dossier();
|
|
10366
|
+
init_sitian_reader();
|
|
10367
|
+
init_unknown_value();
|
|
10368
|
+
}
|
|
10369
|
+
});
|
|
10370
|
+
|
|
10371
|
+
// src/sha256.ts
|
|
10372
|
+
import { createHash } from "node:crypto";
|
|
10373
|
+
function sha256Hex(bytes) {
|
|
10374
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
10375
|
+
}
|
|
10376
|
+
var init_sha256 = __esm({
|
|
10377
|
+
"src/sha256.ts"() {
|
|
10378
|
+
"use strict";
|
|
10379
|
+
}
|
|
10380
|
+
});
|
|
10381
|
+
|
|
10331
10382
|
// src/doctor-evidence.ts
|
|
10332
10383
|
var init_doctor_evidence = __esm({
|
|
10333
10384
|
"src/doctor-evidence.ts"() {
|
|
@@ -10382,18 +10433,6 @@ var init_session_dialogue = __esm({
|
|
|
10382
10433
|
}
|
|
10383
10434
|
});
|
|
10384
10435
|
|
|
10385
|
-
// src/sitian-facade.ts
|
|
10386
|
-
var init_sitian_facade = __esm({
|
|
10387
|
-
"src/sitian-facade.ts"() {
|
|
10388
|
-
"use strict";
|
|
10389
|
-
init_role_run_placement();
|
|
10390
|
-
init_sitian_appender();
|
|
10391
|
-
init_sitian_contracts();
|
|
10392
|
-
init_sitian_appender();
|
|
10393
|
-
init_sitian_reader();
|
|
10394
|
-
}
|
|
10395
|
-
});
|
|
10396
|
-
|
|
10397
10436
|
// src/ticket-provenance.ts
|
|
10398
10437
|
var init_ticket_provenance = __esm({
|
|
10399
10438
|
"src/ticket-provenance.ts"() {
|
|
@@ -11205,6 +11244,7 @@ var init_invocation = __esm({
|
|
|
11205
11244
|
init_activation_ledger_topology();
|
|
11206
11245
|
init_activation_ledger_git();
|
|
11207
11246
|
init_role_run_placement();
|
|
11247
|
+
init_ticket_progress();
|
|
11208
11248
|
init_packaged_role_registry();
|
|
11209
11249
|
init_run_ticket_number();
|
|
11210
11250
|
init_role_run_relocation();
|
|
@@ -336,7 +336,9 @@ export function createPiRoleTurnHost(config) {
|
|
|
336
336
|
const roleEntry = await realpath(resolveInternalRoleEntrypoint(config.packageRoot));
|
|
337
337
|
const extraArgs = buildPiTurnExtraArgs(turnRequest, config.principalAuthority, config.extraPiArgs ?? []);
|
|
338
338
|
const args = buildExplicitInternalActivationArgs(roleEntry, extraArgs);
|
|
339
|
-
const
|
|
339
|
+
const transportBody = piUserDialogueBody(turnRequest);
|
|
340
|
+
// #1199: progress instruction is these same body bytes (actual seat input).
|
|
341
|
+
const stdin = encodeUserDialogueStdin(transportBody);
|
|
340
342
|
// Shared envelope isolates this call's court identity: omitting courtAttemptId
|
|
341
343
|
// must not inherit a parent process.env.AK_ROLE_COURT_ATTEMPT (#637).
|
|
342
344
|
const env = {
|
|
@@ -362,6 +364,9 @@ export function createPiRoleTurnHost(config) {
|
|
|
362
364
|
delete env.AK_ROLE_HOST;
|
|
363
365
|
else
|
|
364
366
|
env.AK_ROLE_HOST = request.host.trim();
|
|
367
|
+
// #1199: 传召词 is unknown-length body — never argv/env (execve ARG_MAX / E2BIG).
|
|
368
|
+
// Typed stdin envelope carries dialogue + optional progress 传召词.
|
|
369
|
+
delete env.AK_ROLE_SUMMONS_INSTRUCTION;
|
|
365
370
|
// #1132: the one effective delivery-request ceiling travels to the child
|
|
366
371
|
// on its own env so the in-child role runtime and the worker submission
|
|
367
372
|
// gate count with the same configured number the AK seam resolved. Omit
|
|
@@ -395,7 +395,10 @@ export async function resolveReviewSeatDialogueBody(input) {
|
|
|
395
395
|
return undefined;
|
|
396
396
|
return await loadLedgerPeerBody(sourceRunPath, input.projectRoot, input.home);
|
|
397
397
|
}
|
|
398
|
-
|
|
398
|
+
/**
|
|
399
|
+
* Initial host prompt for this turn (#1199: progress instruction = these bytes).
|
|
400
|
+
*/
|
|
401
|
+
async function resolveInitialTurnPrompt(admitted, env) {
|
|
399
402
|
const record = roleRecord(admitted.role);
|
|
400
403
|
if ("reaskPrompt" in record && record.reaskPrompt === true) {
|
|
401
404
|
const sourceRunPath = admittedSourceRunPath(admitted);
|
|
@@ -513,7 +516,7 @@ async function dispatchAdmitted(admitted, env, io) {
|
|
|
513
516
|
if (activeEnv.correlationId !== undefined && activeEnv.correlationId.trim() !== "") {
|
|
514
517
|
await recordAdmittedCorrelation(admitted, activeEnv.correlationId);
|
|
515
518
|
}
|
|
516
|
-
const
|
|
519
|
+
const initialPrompt = await resolveInitialTurnPrompt(admitted, activeEnv);
|
|
517
520
|
const auto = "inCallAutoResume" in record && record.inCallAutoResume === true;
|
|
518
521
|
if (auto) {
|
|
519
522
|
// #1208: auto-resume resends this turn's actual content, never a filler phrase.
|
|
@@ -523,11 +526,11 @@ async function dispatchAdmitted(admitted, env, io) {
|
|
|
523
526
|
io: turnIo,
|
|
524
527
|
buildInitialRequest: () => buildInstructionSeatTurnRequest(admitted, roleTurnOptions(activeEnv, admitted, {
|
|
525
528
|
kind: "initial",
|
|
526
|
-
prompt:
|
|
529
|
+
prompt: initialPrompt,
|
|
527
530
|
})),
|
|
528
531
|
buildResumeRequest: () => buildInstructionSeatTurnRequest(admitted, roleTurnOptions(activeEnv, admitted, {
|
|
529
532
|
kind: "resume",
|
|
530
|
-
prompt:
|
|
533
|
+
prompt: initialPrompt,
|
|
531
534
|
})),
|
|
532
535
|
adapters,
|
|
533
536
|
...(activeEnv.engine === undefined ? {} : { effectiveEngine: activeEnv.engine }),
|
|
@@ -539,7 +542,7 @@ async function dispatchAdmitted(admitted, env, io) {
|
|
|
539
542
|
io: turnIo,
|
|
540
543
|
request: buildInstructionSeatTurnRequest(admitted, roleTurnOptions(activeEnv, admitted, {
|
|
541
544
|
kind: "initial",
|
|
542
|
-
prompt:
|
|
545
|
+
prompt: initialPrompt,
|
|
543
546
|
})),
|
|
544
547
|
adapters,
|
|
545
548
|
...(activeEnv.engine === undefined ? {} : { effectiveEngine: activeEnv.engine }),
|
|
@@ -650,7 +653,7 @@ function resumeSameParentInstructionSeat(input) {
|
|
|
650
653
|
});
|
|
651
654
|
}
|
|
652
655
|
/**
|
|
653
|
-
* Same delivery rule as
|
|
656
|
+
* Same delivery rule as resolveInitialTurnPrompt for same-parent resume summons.
|
|
654
657
|
* Shared resolver owns the input choice — callers only pass env fields.
|
|
655
658
|
*/
|
|
656
659
|
async function sameParentDialogue(env, fallback, sourceRunPath, projectRoot, role) {
|
|
@@ -736,7 +739,7 @@ async function runCountersignBody(parsed, env, io) {
|
|
|
736
739
|
// #1208 C1 / #1166 J11: one shared initial-prompt seam (incl. file flags).
|
|
737
740
|
const turnProjection = roleTurnOptions(env, admitted, {
|
|
738
741
|
kind: "initial",
|
|
739
|
-
prompt: await
|
|
742
|
+
prompt: await resolveInitialTurnPrompt(admitted, env),
|
|
740
743
|
});
|
|
741
744
|
const turnRequest = buildInstructionSeatTurnRequest(admitted, turnProjection);
|
|
742
745
|
const result = await runPostAdmissionOneShot({
|
|
@@ -8,7 +8,8 @@ import { readFile, realpath, rename, writeFile, } from "node:fs/promises";
|
|
|
8
8
|
import { dirname, isAbsolute, join, resolve, sep } from "node:path";
|
|
9
9
|
import { activationBookDirectory, ensureRealDirectoryTree, homeFromRunDirectory, pathContainedIn, resolveActivationLedgerHome, } from "../activation-ledger-topology.js";
|
|
10
10
|
import { resolveBookKeyFromGit } from "../activation-ledger-git.js";
|
|
11
|
-
import { ensureRoleRunDirectory, ensureRoleRunPlacement,
|
|
11
|
+
import { ensureRoleRunDirectory, ensureRoleRunPlacement, isUnboundRunDirectory, listBookRunDirectories, roleRunPlacement, sessionDirectoryOf, sessionFileIn, } from "../role-run-placement.js";
|
|
12
|
+
import { relocateTicketProgressForLeg } from "../ticket-progress.js";
|
|
12
13
|
import { packagedAdmittedSubject, packagedArgvResult, packagedBareToken, packagedBaseIsRevision, packagedEmitsAuthorityRefs, packagedPublicInstructionSubject, packagedRoleMetadata, packagedStoresSourceRunRaw, packagedSubjectChoices, } from "../packaged-role-registry.js";
|
|
13
14
|
import { isSafePositiveTicketNumber, parseTicketNumber, readBoardTicketNumber, requireSafePositiveTicketNumber, } from "../run-ticket-number.js";
|
|
14
15
|
import { rewriteAdmittedRoleRunPage, } from "../role-run-relocation.js";
|
|
@@ -243,12 +244,80 @@ export async function recordAdmittedCorrelation(admitted, correlationId) {
|
|
|
243
244
|
mutable.correlationId = correlationId;
|
|
244
245
|
mutable.correlationIds = correlationIds;
|
|
245
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* #1199 R2: registered 起居郎 legs that already belong on this ticket.
|
|
249
|
+
* Unbound source → whole-leg rename + publish; already under ticket → publish
|
|
250
|
+
* leftover staging only. No scan of unregistered siblings.
|
|
251
|
+
*/
|
|
252
|
+
async function relocateRegisteredChildDiarists(input) {
|
|
253
|
+
const childRunIds = readPageSync(input.parentRunDirectory, "admitted")?.childDiaristRunIds;
|
|
254
|
+
for (const childRunId of Array.isArray(childRunIds) ? childRunIds : []) {
|
|
255
|
+
if (typeof childRunId !== "string")
|
|
256
|
+
continue;
|
|
257
|
+
const childTarget = roleRunPlacement(input.ledgerHome, {
|
|
258
|
+
bookKey: input.bookKey,
|
|
259
|
+
subject: { ticketNumber: input.ticketNumber },
|
|
260
|
+
runId: childRunId,
|
|
261
|
+
role: "diarist",
|
|
262
|
+
});
|
|
263
|
+
const unboundChildDirectory = roleRunPlacement(input.ledgerHome, {
|
|
264
|
+
bookKey: input.bookKey,
|
|
265
|
+
subject: { unbound: true },
|
|
266
|
+
runId: childRunId,
|
|
267
|
+
role: "diarist",
|
|
268
|
+
}).runDirectory;
|
|
269
|
+
if (existsSync(unboundChildDirectory)) {
|
|
270
|
+
input.authority.seal(childTarget);
|
|
271
|
+
await bindTicketNumberOnRunDirectory(unboundChildDirectory, input.ticketNumber);
|
|
272
|
+
await rehomeUnboundTicketProvenance(unboundChildDirectory, input.ticketNumber, input.projectRoot, homeFromRunDirectory(input.parentRunDirectory));
|
|
273
|
+
ensureRoleRunDirectory(input.ledgerHome, dirname(childTarget.runDirectory));
|
|
274
|
+
// #1199: whole-leg rename first; originals travel with the directory.
|
|
275
|
+
await rename(unboundChildDirectory, childTarget.runDirectory);
|
|
276
|
+
relocateTicketProgressForLeg({
|
|
277
|
+
runDirectory: childTarget.runDirectory,
|
|
278
|
+
});
|
|
279
|
+
// Finished child legs will not settle again; refresh derived host.original
|
|
280
|
+
// after the rename commit. A derived render fault must not undo or block
|
|
281
|
+
// the committed placement (#1161 L1) — note and keep the true cause.
|
|
282
|
+
try {
|
|
283
|
+
renderCurrentSync(childTarget.runDirectory);
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
process.stderr.write(`[invocation] current.json render refused after child relocate; placement kept: ${childTarget.runDirectory}: ${errorText(error)}\n`);
|
|
287
|
+
}
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
// Prior partial relocate left the child under the ticket with staging still held.
|
|
291
|
+
if (existsSync(childTarget.runDirectory)) {
|
|
292
|
+
relocateTicketProgressForLeg({
|
|
293
|
+
runDirectory: childTarget.runDirectory,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
246
298
|
/** File a role run under its latest typed ticket identity. */
|
|
247
299
|
export async function relocateAdmittedRunToTicket(admitted, authority, heldLease) {
|
|
248
|
-
if (admitted.ticketNumber === undefined
|
|
300
|
+
if (admitted.ticketNumber === undefined)
|
|
249
301
|
return undefined;
|
|
302
|
+
const ledgerHome = resolveActivationLedgerHome(homeFromRunDirectory(admitted.runDirectory));
|
|
303
|
+
// Already under the ticket: publish leftover progress.jsonl (self + registered children).
|
|
304
|
+
if (!isUnboundRunDirectory(admitted.runDirectory)) {
|
|
305
|
+
relocateTicketProgressForLeg({
|
|
306
|
+
runDirectory: admitted.runDirectory,
|
|
307
|
+
});
|
|
308
|
+
if (admitted.role !== "diarist") {
|
|
309
|
+
await relocateRegisteredChildDiarists({
|
|
310
|
+
parentRunDirectory: admitted.runDirectory,
|
|
311
|
+
bookKey: admitted.bookKey,
|
|
312
|
+
ticketNumber: admitted.ticketNumber,
|
|
313
|
+
projectRoot: admitted.projectRoot,
|
|
314
|
+
ledgerHome,
|
|
315
|
+
authority,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
return undefined;
|
|
319
|
+
}
|
|
250
320
|
const oldRunDirectory = admitted.runDirectory;
|
|
251
|
-
const ledgerHome = resolveActivationLedgerHome(homeFromRunDirectory(oldRunDirectory));
|
|
252
321
|
const target = roleRunPlacement(ledgerHome, {
|
|
253
322
|
bookKey: admitted.bookKey,
|
|
254
323
|
subject: { ticketNumber: admitted.ticketNumber },
|
|
@@ -256,54 +325,41 @@ export async function relocateAdmittedRunToTicket(admitted, authority, heldLease
|
|
|
256
325
|
role: admitted.role,
|
|
257
326
|
});
|
|
258
327
|
ensureRoleRunDirectory(ledgerHome, dirname(target.runDirectory));
|
|
259
|
-
//
|
|
260
|
-
|
|
261
|
-
const principal = authority.seal(target);
|
|
328
|
+
// Pre-flight seal; final seal after the filesystem commit.
|
|
329
|
+
authority.seal(target);
|
|
262
330
|
if (admitted.role !== "diarist") {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const childTarget = roleRunPlacement(ledgerHome, {
|
|
272
|
-
bookKey: admitted.bookKey,
|
|
273
|
-
subject: { ticketNumber: admitted.ticketNumber },
|
|
274
|
-
runId: childRunId,
|
|
275
|
-
role: "diarist",
|
|
276
|
-
});
|
|
277
|
-
authority.seal(childTarget);
|
|
278
|
-
await bindTicketNumberOnRunDirectory(childDirectory, admitted.ticketNumber);
|
|
279
|
-
await rehomeUnboundTicketProvenance(childDirectory, admitted.ticketNumber, admitted.projectRoot, homeFromRunDirectory(oldRunDirectory));
|
|
280
|
-
ensureRoleRunDirectory(ledgerHome, dirname(childTarget.runDirectory));
|
|
281
|
-
await rename(childDirectory, childTarget.runDirectory);
|
|
282
|
-
// Finished child legs will not settle again; refresh derived host.original
|
|
283
|
-
// after the rename commit. A derived render fault must not undo or block
|
|
284
|
-
// the committed placement (#1161 L1) — note and keep the true cause.
|
|
285
|
-
try {
|
|
286
|
-
renderCurrentSync(childTarget.runDirectory);
|
|
287
|
-
}
|
|
288
|
-
catch (error) {
|
|
289
|
-
process.stderr.write(`[invocation] current.json render refused after child relocate; placement kept: ${childTarget.runDirectory}: ${errorText(error)}\n`);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
331
|
+
await relocateRegisteredChildDiarists({
|
|
332
|
+
parentRunDirectory: oldRunDirectory,
|
|
333
|
+
bookKey: admitted.bookKey,
|
|
334
|
+
ticketNumber: admitted.ticketNumber,
|
|
335
|
+
projectRoot: admitted.projectRoot,
|
|
336
|
+
ledgerHome,
|
|
337
|
+
authority,
|
|
338
|
+
});
|
|
292
339
|
}
|
|
293
340
|
// The first ticket assignment moves only an unbound diarist's own diary.
|
|
294
341
|
if (admitted.role === "diarist") {
|
|
295
342
|
await rehomeUnboundTicketProvenance(oldRunDirectory, admitted.ticketNumber, admitted.projectRoot, homeFromRunDirectory(oldRunDirectory));
|
|
296
343
|
}
|
|
297
344
|
// Rename commits the run placement. Diary assignment above is a Sitian append
|
|
298
|
-
// outside the atomic directory move.
|
|
299
|
-
// Persisted paths are resolved from typed run identity on read.
|
|
345
|
+
// outside the atomic directory move. Session/receipts/progress travel with the leg.
|
|
300
346
|
await rename(oldRunDirectory, target.runDirectory);
|
|
301
347
|
// rename moved the open lock inode with the directory. Transfer cleanup and
|
|
302
|
-
//
|
|
303
|
-
//
|
|
348
|
+
// live path ownership immediately after the commit — before final seal/render
|
|
349
|
+
// (#1161 L1 / BASE order). Live handles first so mid-turn setSessionFile sees
|
|
350
|
+
// the ticket leaf; final seal uses the post-move existence landing.
|
|
304
351
|
heldLease?.relocate(target.runDirectory);
|
|
352
|
+
const actualSessionDirectory = sessionDirectoryOf(target.runDirectory);
|
|
353
|
+
const principal = authority.seal({
|
|
354
|
+
sessionDirectory: actualSessionDirectory,
|
|
355
|
+
sessionFile: sessionFileIn(actualSessionDirectory),
|
|
356
|
+
});
|
|
305
357
|
rewriteAdmittedRoleRunPage(admitted, [{ oldRunDirectory, newRunDirectory: target.runDirectory }]);
|
|
306
358
|
admitted.principal = principal;
|
|
359
|
+
// After whole-leg rename + live-handle handoff: fill rounds and append ticket current.
|
|
360
|
+
relocateTicketProgressForLeg({
|
|
361
|
+
runDirectory: target.runDirectory,
|
|
362
|
+
});
|
|
307
363
|
// current.json projects host.original from this run directory. Ownership is
|
|
308
364
|
// already transferred; a refuse still carries the true cause to the caller
|
|
309
365
|
// (#1161 L1) without leaving the leg under the unbound path.
|