@akagilnc/pi-workflow-roles 0.1.4932 → 0.1.4951

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.
@@ -285,7 +285,7 @@ function projectTicketProvenanceSessions(value2) {
285
285
  }
286
286
  function projectTicketProvenanceHeader(value2) {
287
287
  if (!isRecord(value2)) return void 0;
288
- const ticket = positiveInteger(value2.ticket);
288
+ const ticket = value2.ticket === null ? null : positiveInteger(value2.ticket);
289
289
  if (ticket === void 0) return void 0;
290
290
  if (typeof value2.repo !== "string") return void 0;
291
291
  if (typeof value2.createdAt !== "string" || typeof value2.updatedAt !== "string") {
@@ -14976,6 +14976,77 @@ var init_merger_git_state = __esm({
14976
14976
  }
14977
14977
  });
14978
14978
 
14979
+ // src/ledger-session-read.ts
14980
+ var init_ledger_session_read = __esm({
14981
+ "src/ledger-session-read.ts"() {
14982
+ "use strict";
14983
+ }
14984
+ });
14985
+
14986
+ // src/session-dialogue.ts
14987
+ var init_session_dialogue = __esm({
14988
+ "src/session-dialogue.ts"() {
14989
+ "use strict";
14990
+ }
14991
+ });
14992
+
14993
+ // src/sitian-contracts.ts
14994
+ var init_sitian_contracts = __esm({
14995
+ "src/sitian-contracts.ts"() {
14996
+ "use strict";
14997
+ }
14998
+ });
14999
+
15000
+ // src/sitian-appender.ts
15001
+ var S4_SUBMISSION_LEDGER_KINDS;
15002
+ var init_sitian_appender = __esm({
15003
+ "src/sitian-appender.ts"() {
15004
+ "use strict";
15005
+ init_activation_ledger_git();
15006
+ init_activation_ledger_topology();
15007
+ init_sitian_contracts();
15008
+ S4_SUBMISSION_LEDGER_KINDS = /* @__PURE__ */ new Set([
15009
+ "candidate",
15010
+ "roundContext",
15011
+ "outcome",
15012
+ "sealed",
15013
+ "post-seal-anomaly"
15014
+ ]);
15015
+ }
15016
+ });
15017
+
15018
+ // src/sitian-reader.ts
15019
+ var init_sitian_reader = __esm({
15020
+ "src/sitian-reader.ts"() {
15021
+ "use strict";
15022
+ }
15023
+ });
15024
+
15025
+ // src/sitian-facade.ts
15026
+ var init_sitian_facade = __esm({
15027
+ "src/sitian-facade.ts"() {
15028
+ "use strict";
15029
+ init_sitian_appender();
15030
+ init_sitian_contracts();
15031
+ init_sitian_appender();
15032
+ init_sitian_reader();
15033
+ }
15034
+ });
15035
+
15036
+ // src/ticket-provenance.ts
15037
+ var init_ticket_provenance = __esm({
15038
+ "src/ticket-provenance.ts"() {
15039
+ "use strict";
15040
+ init_activation_ledger_git();
15041
+ init_activation_ledger_topology();
15042
+ init_ledger_session_read();
15043
+ init_run_ticket_number();
15044
+ init_session_dialogue();
15045
+ init_sitian_facade();
15046
+ init_ticket_provenance_contracts();
15047
+ }
15048
+ });
15049
+
14979
15050
  // src/uuidv7.ts
14980
15051
  var init_uuidv7 = __esm({
14981
15052
  "src/uuidv7.ts"() {
@@ -15793,6 +15864,7 @@ var init_invocation = __esm({
15793
15864
  init_merger_git_state();
15794
15865
  init_merger_contracts();
15795
15866
  init_sha256();
15867
+ init_ticket_provenance();
15796
15868
  init_uuidv7();
15797
15869
  init_notary_contracts();
15798
15870
  init_notary_source_run();
@@ -177414,31 +177486,6 @@ var init_dist6 = __esm({
177414
177486
  }
177415
177487
  });
177416
177488
 
177417
- // src/sitian-contracts.ts
177418
- var init_sitian_contracts = __esm({
177419
- "src/sitian-contracts.ts"() {
177420
- "use strict";
177421
- }
177422
- });
177423
-
177424
- // src/sitian-appender.ts
177425
- var S4_SUBMISSION_LEDGER_KINDS;
177426
- var init_sitian_appender = __esm({
177427
- "src/sitian-appender.ts"() {
177428
- "use strict";
177429
- init_activation_ledger_git();
177430
- init_activation_ledger_topology();
177431
- init_sitian_contracts();
177432
- S4_SUBMISSION_LEDGER_KINDS = /* @__PURE__ */ new Set([
177433
- "candidate",
177434
- "roundContext",
177435
- "outcome",
177436
- "sealed",
177437
- "post-seal-anomaly"
177438
- ]);
177439
- }
177440
- });
177441
-
177442
177489
  // scripts/migrate-book-topology.ts
177443
177490
  import { homedir as homedir4 } from "node:os";
177444
177491
  import { join as join15, resolve as resolve9 } from "node:path";
@@ -179190,7 +179237,7 @@ function tryBareTicketProvenanceVolume(lines) {
179190
179237
  if (!first.ok) return void 0;
179191
179238
  if (recordClassOfKind(first.value.kind) !== void 0) return void 0;
179192
179239
  const header = projectTicketProvenanceHeader(first.value);
179193
- if (header === void 0) return void 0;
179240
+ if (header === void 0 || header.ticket === null) return void 0;
179194
179241
  return { ticket: header.ticket, body };
179195
179242
  }
179196
179243
  async function placeBareTicketProvenanceVolume(context, bookKey, writes, filePath, bare, outcomes) {
@@ -163,6 +163,7 @@ export async function invokeCourtDiarist(input, env, io) {
163
163
  kind: "escalate",
164
164
  diagnostic: courtDiaristEscalateDiagnostic(roleOutcome, submissions),
165
165
  },
166
+ ...(result.admitted === undefined ? {} : { admitted: result.admitted }),
166
167
  };
167
168
  }
168
169
  if (result.exitCode !== 0) {
@@ -171,6 +172,7 @@ export async function invokeCourtDiarist(input, env, io) {
171
172
  : result.stderr?.trim() || `exit ${result.exitCode}`;
172
173
  return {
173
174
  identity: { kind: "unbound" },
175
+ ...(result.admitted === undefined ? {} : { admitted: result.admitted }),
174
176
  failedWithoutEscalate: {
175
177
  diagnostic: `court diarist station failed for ${input.failureLabel}: ${diagnostic}`,
176
178
  },
@@ -186,10 +188,12 @@ export async function invokeCourtDiarist(input, env, io) {
186
188
  ticketNumber: asserted,
187
189
  ...(courtTicketNumbers === undefined ? {} : { courtTicketNumbers }),
188
190
  },
191
+ ...(result.admitted === undefined ? {} : { admitted: result.admitted }),
189
192
  };
190
193
  }
191
194
  return {
192
195
  identity: { kind: "unbound" },
196
+ ...(result.admitted === undefined ? {} : { admitted: result.admitted }),
193
197
  };
194
198
  }
195
199
  /**
@@ -4,7 +4,7 @@
4
4
  * starts two ordinary single-axis runs here. Countersign keeps deferred
5
5
  * identity on this entry; the court diarist station stays in countersign-run.
6
6
  */
7
- import { resolve } from "node:path";
7
+ import { resolve, sep } from "node:path";
8
8
  import { isSafePositiveTicketNumber, readBoardTicketNumber } from "../run-ticket-number.js";
9
9
  import { NotarySourceRunError, resolveNotarySourceRunLocator } from "../notary-source-run.js";
10
10
  import { engineSessionMaterialFromOptions, pickEngineAxis } from "../package-resources/engine-material.js";
@@ -12,7 +12,7 @@ import { loadPackagedMethodSkillMaterial, } from "../package-resources/method-sk
12
12
  import { packagedAdmitsCountersign, packagedBindsBoardTicket, packagedMethodLoadFailureCause, packagedRebindSourceOnResume, packagedRoleMetadata, } from "../packaged-role-registry.js";
13
13
  import { isAuditorSoulRole } from "../auditor-soul.js";
14
14
  import { CliUsageError } from "./cli-errors.js";
15
- import { admitPublicRole, bindAdmittedTicketNumber, bindCourtTicketNumbersOnAdmitted, buildInstructionTransportPrompt, materializeCountersignInvocation, persistAdmittedSourceRunPath, recordAdmittedCorrelation, relocateAdmittedRunToTicket, withPreparedAttachments, } from "./invocation.js";
15
+ import { admitPublicRole, bindAdmittedTicketNumber, bindCourtTicketNumbersOnAdmitted, buildInstructionTransportPrompt, materializeCountersignInvocation, persistAdmittedSourceRunPath, recordAdmittedCorrelation, recordChildDiaristRun, relocateAdmittedRunToTicket, withPreparedAttachments, } from "./invocation.js";
16
16
  import { presentControlledFailure, prepareSummonsResumeMaterials, resolveResumeMethodMaterialAdapters, roleTurnOptions, runPostAdmissionOneShot, runPostAdmissionResumable, runPostAdmissionSeatResume, resumeTurnRequestProjectionOptions, } from "./post-admission.js";
17
17
  import { buildAutoResumeContinuationPrompt, loadResumablePublicRole, markRunAdmitted, parentRunPathFromGatePointerInstruction, } from "./run-lifecycle.js";
18
18
  import { tryResumeSameTicketSeatRun } from "./seat-ticket-binding.js";
@@ -296,6 +296,7 @@ async function runCountersignBody(parsed, env, io) {
296
296
  let typedTicket;
297
297
  let typedCourtTicketNumbers;
298
298
  let identityDiaristRan = false;
299
+ let unboundDiaristRunId;
299
300
  if (env.runCourtDiaristStation === undefined) {
300
301
  let outcome;
301
302
  try {
@@ -317,11 +318,16 @@ async function runCountersignBody(parsed, env, io) {
317
318
  }, seatAdapters(admitted, env), env.principalAuthority, io);
318
319
  }
319
320
  identityDiaristRan = true;
321
+ if (outcome.admitted?.runDirectory.includes(`${sep}unbound${sep}runs${sep}`)) {
322
+ unboundDiaristRunId = outcome.admitted.runId;
323
+ }
320
324
  if (outcome.identity.kind === "escalate" || outcome.failedWithoutEscalate !== undefined) {
321
325
  const diagnostic = outcome.identity.kind === "escalate"
322
326
  ? outcome.identity.diagnostic
323
327
  : outcome.failedWithoutEscalate?.diagnostic ?? "";
324
328
  await materializeAdmission(isSafePositiveTicketNumber(env.boundTicketNumber) ? env.boundTicketNumber : undefined);
329
+ if (unboundDiaristRunId !== undefined)
330
+ await recordChildDiaristRun(admitted, unboundDiaristRunId);
325
331
  await markRunAdmitted(admitted, env.principalAuthority);
326
332
  return await presentControlledFailure(admitted, {
327
333
  timedOut: false,
@@ -342,6 +348,9 @@ async function runCountersignBody(parsed, env, io) {
342
348
  }
343
349
  await materializeAdmission(typedTicket);
344
350
  await markRunAdmitted(admitted, env.principalAuthority);
351
+ if (unboundDiaristRunId !== undefined) {
352
+ await recordChildDiaristRun(admitted, unboundDiaristRunId);
353
+ }
345
354
  if (gateParentRunPath !== undefined) {
346
355
  await persistAdmittedSourceRunPath(admitted, gateParentRunPath);
347
356
  admitted = { ...admitted, sourceRunPath: gateParentRunPath };
@@ -587,6 +596,9 @@ export async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
587
596
  ...(env.signal === undefined ? {} : { signal: env.signal }),
588
597
  ...(env.hostAdapters === undefined ? {} : { hostAdapters: env.hostAdapters }),
589
598
  }, io);
599
+ if (outcome.admitted?.runDirectory.includes(`${sep}unbound${sep}runs${sep}`)) {
600
+ await recordChildDiaristRun(admitted, outcome.admitted.runId);
601
+ }
590
602
  if (outcome.identity.kind === "escalate" || outcome.failedWithoutEscalate !== undefined) {
591
603
  const diagnostic = outcome.identity.kind === "escalate"
592
604
  ? outcome.identity.diagnostic
@@ -600,6 +612,10 @@ export async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
600
612
  }
601
613
  if (outcome.identity.kind === "ticket") {
602
614
  try {
615
+ if (outcome.admitted === undefined)
616
+ throw new Error("court diarist ticket has no admitted run");
617
+ await bindAdmittedTicketNumber(outcome.admitted, outcome.identity.ticketNumber);
618
+ await relocateAdmittedRunToTicket(outcome.admitted, env.principalAuthority);
603
619
  await bindAdmittedTicketNumber(admitted, outcome.identity.ticketNumber);
604
620
  await relocateAdmittedRunToTicket(admitted, env.principalAuthority);
605
621
  }
@@ -22,6 +22,7 @@ import { FixerPacketValidationError, parseFixerPrerequisites, } from "../package
22
22
  import { createProductionMergerGitState } from "../merger-git-state.js";
23
23
  import { validateMergerInput, } from "../merger-contracts.js";
24
24
  import { sha256Hex } from "../sha256.js";
25
+ import { rehomeUnboundTicketProvenance } from "../ticket-provenance.js";
25
26
  import { uuidv7 } from "../uuidv7.js";
26
27
  import { NOTARY_FIXED_KICKOFF, } from "../notary-contracts.js";
27
28
  import { NotarySourceRunError, resolveNotarySourceRunLocator, } from "../notary-source-run.js";
@@ -244,9 +245,36 @@ export async function relocateAdmittedRunToTicket(admitted, authority, heldLease
244
245
  // Host sealing is pure identity projection, but may reject the coordinates.
245
246
  // Keep that failure before the filesystem commit point.
246
247
  const principal = authority.seal(target);
247
- // Rename is the only durable commit. Persisted paths are resolved from typed
248
- // run identity on read, so online relocation never writes unleased peers or
249
- // pretends a directory rename plus page rewrites form one transaction.
248
+ if (admitted.role !== "diarist") {
249
+ const parentPage = JSON.parse(await readFile(admitted.admittedRequestPath, "utf8"));
250
+ const childRunIds = parentPage.childDiaristRunIds;
251
+ for (const childRunId of Array.isArray(childRunIds) ? childRunIds : []) {
252
+ if (typeof childRunId !== "string")
253
+ continue;
254
+ const childDirectory = join(dirname(oldRunDirectory), `${childRunId}@diarist`);
255
+ const childTarget = roleRunPlacement(ledgerHome, {
256
+ bookKey: admitted.bookKey,
257
+ subject: { ticketNumber: admitted.ticketNumber },
258
+ runId: childRunId,
259
+ role: "diarist",
260
+ });
261
+ authority.seal(childTarget);
262
+ if (!existsSync(childDirectory) && existsSync(childTarget.runDirectory))
263
+ continue;
264
+ await bindTicketNumberOnRunDirectory(childDirectory, admitted.ticketNumber);
265
+ await rehomeUnboundTicketProvenance(childDirectory, admitted.ticketNumber, admitted.projectRoot, homeFromRunDirectory(oldRunDirectory));
266
+ ensureRoleRunDirectory(ledgerHome, dirname(childTarget.runDirectory));
267
+ await rename(childDirectory, childTarget.runDirectory);
268
+ }
269
+ }
270
+ // An identity diarist can file before its caller obtains a ticket. Both its
271
+ // own bind and the caller's later bind use this existing relocation seam.
272
+ if (admitted.role === "diarist") {
273
+ await rehomeUnboundTicketProvenance(oldRunDirectory, admitted.ticketNumber, admitted.projectRoot, homeFromRunDirectory(oldRunDirectory));
274
+ }
275
+ // Rename commits the run placement. Diary assignment above is an idempotent
276
+ // Sitian append, not part of an atomic transaction with this directory move.
277
+ // Persisted paths are resolved from typed run identity on read.
250
278
  await rename(oldRunDirectory, target.runDirectory);
251
279
  // rename moved the open lock inode with the directory. Transfer cleanup
252
280
  // ownership immediately after the commit.
@@ -267,6 +295,15 @@ export async function relocateAdmittedRunToTicket(admitted, authority, heldLease
267
295
  admitted.principal = principal;
268
296
  return { oldRunDirectory, newRunDirectory: target.runDirectory };
269
297
  }
298
+ /** Persist the exact child identity; later parent binding never inspects siblings. */
299
+ export async function recordChildDiaristRun(parent, childRunId) {
300
+ const page = JSON.parse(await readFile(parent.admittedRequestPath, "utf8"));
301
+ const existing = Array.isArray(page.childDiaristRunIds)
302
+ ? page.childDiaristRunIds.filter((runId) => typeof runId === "string")
303
+ : [];
304
+ const childDiaristRunIds = existing.includes(childRunId) ? existing : [...existing, childRunId];
305
+ await writeFile(parent.admittedRequestPath, `${JSON.stringify({ ...page, childDiaristRunIds }, null, 2)}\n`, "utf8");
306
+ }
270
307
  /**
271
308
  * Bind ticket identity onto a run directory's durable pages when the admitted
272
309
  * object is not in hand (起居郎 accept hook after LLM assertion, #771).