@akagilnc/pi-workflow-roles 0.1.5289 → 0.1.5301
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/README.md +7 -3
- package/README.zh-CN.md +7 -3
- package/dist/acp-host/production-host.js +97 -462
- package/dist/diarist-contracts.js +20 -96
- package/dist/headless-host/production-host.js +97 -462
- package/dist/migrate-book-topology.js +75 -77
- package/dist/public-cli/countersign-run.js +3 -124
- package/dist/public-cli/instruction-seat-run.js +5 -97
- package/dist/public-cli/invocation.js +0 -33
- package/dist/public-cli/main.js +10 -362
- package/dist/public-cli/post-admission.js +2 -14
- package/dist/public-cli/run-lifecycle.js +0 -85
- package/dist/public-role-summons.js +2 -2
- package/dist/ticket-provenance.js +25 -29
- package/package.json +1 -1
- package/resources/diarist-collect.md +4 -4
- package/src/diarist-contracts.ts +24 -116
- package/src/diarist-role.ts +39 -50
- package/src/diarist.ts +9 -29
- package/src/public-cli/countersign-run.ts +7 -184
- package/src/public-cli/instruction-seat-run.ts +6 -101
- package/src/public-cli/invocation.ts +2 -64
- package/src/public-cli/post-admission.ts +2 -15
- package/src/public-cli/run-lifecycle.ts +0 -117
- package/src/public-role-summons.ts +3 -3
- package/src/role-runtime.ts +13 -7
- package/src/ticket-provenance.ts +31 -44
|
@@ -31,10 +31,6 @@ export {
|
|
|
31
31
|
import type { FixerPhase } from "../package-contracts/fixer-output.ts";
|
|
32
32
|
import type { FixerPrerequisite } from "../package-contracts/fixer-packet.ts";
|
|
33
33
|
import { parseCollectorRepository } from "../collector-config.ts";
|
|
34
|
-
import {
|
|
35
|
-
interpretDurableCourtTicketNumbers,
|
|
36
|
-
sameCourtTicketNumbers,
|
|
37
|
-
} from "../diarist-contracts.ts";
|
|
38
34
|
import type { DoctorCaseIdentity } from "../doctor-contracts.ts";
|
|
39
35
|
import type { NotarySourceRunLocator } from "../notary-contracts.ts";
|
|
40
36
|
import {
|
|
@@ -1177,13 +1173,6 @@ type LoadedAdmittedRequestFields = {
|
|
|
1177
1173
|
readonly derived?: DerivedMergerEnvelope;
|
|
1178
1174
|
readonly correlationId?: string;
|
|
1179
1175
|
readonly ticketNumber?: number;
|
|
1180
|
-
/** #871 typed co-review set restored on countersign resume. */
|
|
1181
|
-
readonly courtTicketNumbers?: readonly number[];
|
|
1182
|
-
/**
|
|
1183
|
-
* #871 durable set present-but-damaged diagnostic. Countersign resume settles
|
|
1184
|
-
* controlled failure with this text; not a structural usage rejection.
|
|
1185
|
-
*/
|
|
1186
|
-
readonly courtTicketNumbersDamage?: string;
|
|
1187
1176
|
/** Collector — admitted repository/PR identity restored on resume (#633). */
|
|
1188
1177
|
readonly prNumber?: number;
|
|
1189
1178
|
readonly repository?: string;
|
|
@@ -1223,90 +1212,13 @@ function parsePersistedTicketIdentity(
|
|
|
1223
1212
|
};
|
|
1224
1213
|
}
|
|
1225
1214
|
|
|
1226
|
-
/**
|
|
1227
|
-
* #871 durable set from one run page.
|
|
1228
|
-
* Absent → absent. Present damage keeps the original reason (no throw here).
|
|
1229
|
-
*/
|
|
1230
|
-
function readDurableCourtTicketNumbersPage(
|
|
1231
|
-
record: Record<string, unknown>,
|
|
1232
|
-
principalTicket: number | undefined,
|
|
1233
|
-
pageLabel: string,
|
|
1234
|
-
):
|
|
1235
|
-
| { readonly kind: "absent" }
|
|
1236
|
-
| { readonly kind: "ok"; readonly tickets: readonly number[] }
|
|
1237
|
-
| { readonly kind: "damage"; readonly reason: string } {
|
|
1238
|
-
const interpreted = interpretDurableCourtTicketNumbers(record, {
|
|
1239
|
-
...(principalTicket === undefined ? {} : { principalTicket }),
|
|
1240
|
-
});
|
|
1241
|
-
if (interpreted.kind === "damage") {
|
|
1242
|
-
return {
|
|
1243
|
-
kind: "damage",
|
|
1244
|
-
reason: `role run ${pageLabel} courtTicketNumbers is damaged: ${interpreted.reason}`,
|
|
1245
|
-
};
|
|
1246
|
-
}
|
|
1247
|
-
if (interpreted.kind === "ok") {
|
|
1248
|
-
return { kind: "ok", tickets: interpreted.tickets };
|
|
1249
|
-
}
|
|
1250
|
-
return { kind: "absent" };
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
/**
|
|
1254
|
-
* Merge admitted + invocation #871 sets.
|
|
1255
|
-
* Both present must match; one present wins; both absent stays legacy.
|
|
1256
|
-
* Damage / cross-page mismatch return a diagnostic — countersign resume settles
|
|
1257
|
-
* controlled failure; load itself does not structural-reject.
|
|
1258
|
-
*/
|
|
1259
|
-
function mergeDurableCourtTicketNumbers(input: {
|
|
1260
|
-
readonly admittedRecord: Record<string, unknown> | undefined;
|
|
1261
|
-
readonly invocationRecord: Record<string, unknown> | undefined;
|
|
1262
|
-
readonly principalTicket: number | undefined;
|
|
1263
|
-
}):
|
|
1264
|
-
| { readonly kind: "ok"; readonly tickets?: readonly number[] }
|
|
1265
|
-
| { readonly kind: "damage"; readonly reason: string } {
|
|
1266
|
-
const fromAdmitted =
|
|
1267
|
-
input.admittedRecord === undefined
|
|
1268
|
-
? ({ kind: "absent" } as const)
|
|
1269
|
-
: readDurableCourtTicketNumbersPage(
|
|
1270
|
-
input.admittedRecord,
|
|
1271
|
-
input.principalTicket,
|
|
1272
|
-
"admitted-request",
|
|
1273
|
-
);
|
|
1274
|
-
const fromInvocation =
|
|
1275
|
-
input.invocationRecord === undefined
|
|
1276
|
-
? ({ kind: "absent" } as const)
|
|
1277
|
-
: readDurableCourtTicketNumbersPage(
|
|
1278
|
-
input.invocationRecord,
|
|
1279
|
-
input.principalTicket,
|
|
1280
|
-
"invocation",
|
|
1281
|
-
);
|
|
1282
|
-
if (fromAdmitted.kind === "damage") return fromAdmitted;
|
|
1283
|
-
if (fromInvocation.kind === "damage") return fromInvocation;
|
|
1284
|
-
if (fromAdmitted.kind === "ok" && fromInvocation.kind === "ok") {
|
|
1285
|
-
if (!sameCourtTicketNumbers(fromAdmitted.tickets, fromInvocation.tickets)) {
|
|
1286
|
-
return {
|
|
1287
|
-
kind: "damage",
|
|
1288
|
-
reason:
|
|
1289
|
-
"role run courtTicketNumbers differs between admitted-request and invocation",
|
|
1290
|
-
};
|
|
1291
|
-
}
|
|
1292
|
-
return { kind: "ok", tickets: fromAdmitted.tickets };
|
|
1293
|
-
}
|
|
1294
|
-
if (fromAdmitted.kind === "ok") return { kind: "ok", tickets: fromAdmitted.tickets };
|
|
1295
|
-
if (fromInvocation.kind === "ok") return { kind: "ok", tickets: fromInvocation.tickets };
|
|
1296
|
-
return { kind: "ok" };
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
1215
|
function restoredTicketFields(fields: LoadedAdmittedRequestFields): {
|
|
1300
1216
|
correlationId?: string;
|
|
1301
1217
|
ticketNumber?: number;
|
|
1302
|
-
courtTicketNumbers?: readonly number[];
|
|
1303
1218
|
} {
|
|
1304
1219
|
return {
|
|
1305
1220
|
...(fields.correlationId === undefined ? {} : { correlationId: fields.correlationId }),
|
|
1306
1221
|
...(fields.ticketNumber === undefined ? {} : { ticketNumber: fields.ticketNumber }),
|
|
1307
|
-
...(fields.courtTicketNumbers === undefined
|
|
1308
|
-
? {}
|
|
1309
|
-
: { courtTicketNumbers: fields.courtTicketNumbers }),
|
|
1310
1222
|
};
|
|
1311
1223
|
}
|
|
1312
1224
|
|
|
@@ -1352,10 +1264,6 @@ async function loadResumableRunRecord(
|
|
|
1352
1264
|
let derived: DerivedMergerEnvelope | undefined;
|
|
1353
1265
|
let correlationId: string | undefined;
|
|
1354
1266
|
let ticketNumber: number | undefined;
|
|
1355
|
-
let courtTicketNumbers: readonly number[] | undefined;
|
|
1356
|
-
let courtTicketNumbersDamage: string | undefined;
|
|
1357
|
-
let admittedIdentityRecord: Record<string, unknown> | undefined;
|
|
1358
|
-
let invocationIdentityRecord: Record<string, unknown> | undefined;
|
|
1359
1267
|
let prNumber: number | undefined;
|
|
1360
1268
|
let repository: string | undefined;
|
|
1361
1269
|
let repositoryDisplay: string | undefined;
|
|
@@ -1525,7 +1433,6 @@ async function loadResumableRunRecord(
|
|
|
1525
1433
|
};
|
|
1526
1434
|
}
|
|
1527
1435
|
}
|
|
1528
|
-
admittedIdentityRecord = record;
|
|
1529
1436
|
const fromAdmitted = parsePersistedTicketIdentity(record);
|
|
1530
1437
|
correlationId = fromAdmitted.correlationId;
|
|
1531
1438
|
ticketNumber = fromAdmitted.ticketNumber;
|
|
@@ -1549,7 +1456,6 @@ async function loadResumableRunRecord(
|
|
|
1549
1456
|
!Array.isArray(invocationRaw)
|
|
1550
1457
|
) {
|
|
1551
1458
|
const rec = invocationRaw as Record<string, unknown>;
|
|
1552
|
-
invocationIdentityRecord = rec;
|
|
1553
1459
|
if (typeof rec.provider === "string" && typeof rec.model === "string") {
|
|
1554
1460
|
model = {
|
|
1555
1461
|
provider: rec.provider,
|
|
@@ -1584,19 +1490,6 @@ async function loadResumableRunRecord(
|
|
|
1584
1490
|
);
|
|
1585
1491
|
}
|
|
1586
1492
|
}
|
|
1587
|
-
// #871: resolve set after main ticket so principal membership can be checked.
|
|
1588
|
-
// Present-but-damaged / cross-page mismatch keep diagnostic for countersign
|
|
1589
|
-
// controlled-failure; both-absent stays legacy; single lawful page restores.
|
|
1590
|
-
const mergedSet = mergeDurableCourtTicketNumbers({
|
|
1591
|
-
admittedRecord: admittedIdentityRecord,
|
|
1592
|
-
invocationRecord: invocationIdentityRecord,
|
|
1593
|
-
principalTicket: ticketNumber,
|
|
1594
|
-
});
|
|
1595
|
-
if (mergedSet.kind === "damage") {
|
|
1596
|
-
courtTicketNumbersDamage = mergedSet.reason;
|
|
1597
|
-
} else if (mergedSet.tickets !== undefined) {
|
|
1598
|
-
courtTicketNumbers = mergedSet.tickets;
|
|
1599
|
-
}
|
|
1600
1493
|
const sourceRunLeaf = basename(sourceRunPath ?? "").split("@");
|
|
1601
1494
|
const referencedRunId = sourceRun?.runId ?? sourceRunLeaf[0];
|
|
1602
1495
|
const referencedRole = sourceRun?.role ?? sourceRunLeaf[1];
|
|
@@ -1634,10 +1527,6 @@ async function loadResumableRunRecord(
|
|
|
1634
1527
|
...(derived === undefined ? {} : { derived }),
|
|
1635
1528
|
...(correlationId === undefined ? {} : { correlationId }),
|
|
1636
1529
|
...(ticketNumber === undefined ? {} : { ticketNumber }),
|
|
1637
|
-
...(courtTicketNumbers === undefined ? {} : { courtTicketNumbers }),
|
|
1638
|
-
...(courtTicketNumbersDamage === undefined
|
|
1639
|
-
? {}
|
|
1640
|
-
: { courtTicketNumbersDamage }),
|
|
1641
1530
|
...(prNumber === undefined ? {} : { prNumber }),
|
|
1642
1531
|
...(repository === undefined ? {} : { repository }),
|
|
1643
1532
|
...(repositoryDisplay === undefined ? {} : { repositoryDisplay }),
|
|
@@ -1782,12 +1671,6 @@ function admitResumedRole(loaded: {
|
|
|
1782
1671
|
const admitted: AdmittedCountersignInvocation = {
|
|
1783
1672
|
role: "countersign",
|
|
1784
1673
|
...base,
|
|
1785
|
-
...(base.courtTicketNumbers === undefined
|
|
1786
|
-
? {}
|
|
1787
|
-
: { courtTicketNumbers: base.courtTicketNumbers }),
|
|
1788
|
-
...(fields.courtTicketNumbersDamage === undefined
|
|
1789
|
-
? {}
|
|
1790
|
-
: { courtTicketNumbersDamage: fields.courtTicketNumbersDamage }),
|
|
1791
1674
|
};
|
|
1792
1675
|
return admitted;
|
|
1793
1676
|
}
|
|
@@ -421,8 +421,8 @@ export async function summonPublicRole(
|
|
|
421
421
|
// Nested court stations keep station-child semantics; dual-lens
|
|
422
422
|
// ordinary Reviewer axes opt out (#946 / ADR 0082).
|
|
423
423
|
...(options.stationChild === false ? {} : { stationChild: true }),
|
|
424
|
-
// Forward composition-root adapters so nested
|
|
425
|
-
//
|
|
424
|
+
// Forward composition-root adapters so nested stations (e.g.
|
|
425
|
+
// secretariat → diarist) select the same faux/production table (#924).
|
|
426
426
|
...(options.hostAdapters === undefined
|
|
427
427
|
? {}
|
|
428
428
|
: { hostAdapters: options.hostAdapters }),
|
|
@@ -535,7 +535,7 @@ export async function summonPublicRole(
|
|
|
535
535
|
}
|
|
536
536
|
|
|
537
537
|
const stderr = captured?.stderrText();
|
|
538
|
-
//
|
|
538
|
+
// Secretariat can return its preliminary diarist's escalation verbatim.
|
|
539
539
|
// The terminal's independent run, not the officer, is the gate pointer.
|
|
540
540
|
const runDirectory = result.terminal !== undefined
|
|
541
541
|
&& result.terminal.roleOutcome.role !== options.role
|
package/src/role-runtime.ts
CHANGED
|
@@ -73,6 +73,7 @@ import {
|
|
|
73
73
|
import { SECRETARIAT_OUTPUT_TOOL_NAME } from "./secretariat-contracts.ts";
|
|
74
74
|
import {
|
|
75
75
|
projectDiaristSessions,
|
|
76
|
+
projectDiaristTicketSessions,
|
|
76
77
|
} from "./diarist-contracts.ts";
|
|
77
78
|
import { commitDiaristProjection } from "./diarist.ts";
|
|
78
79
|
import { TicketProvenanceInputError } from "./ticket-provenance.ts";
|
|
@@ -834,7 +835,7 @@ function readDiaristRunCoordinates(ctx: HostContext): {
|
|
|
834
835
|
|
|
835
836
|
/** Plain-language re-ask when diarist bounds cannot be used (#901 / reask-not-explode). */
|
|
836
837
|
const DIARIST_BOUNDS_REASK =
|
|
837
|
-
"
|
|
838
|
+
"边界无法使用。多票请逐票重交 ticketSessions,单票重交 sessions;每卷 path + ranges,每端以原生 id 或本轮行号二选一指名。" as const;
|
|
838
839
|
/**
|
|
839
840
|
* #708 / #779 / #901: 起居郎 public seat on the shared filed-officer envelope.
|
|
840
841
|
* LLM judges ticket + dialogue bounds; mechanical layer reprojects the unique
|
|
@@ -870,18 +871,23 @@ export function createDiaristRoleRuntime(
|
|
|
870
871
|
await bindTicketNumberOnRunDirectory(coords.runDirectory, ticketNumber);
|
|
871
872
|
}
|
|
872
873
|
}
|
|
873
|
-
const
|
|
874
|
-
|
|
874
|
+
const singleSessions = submitted && !Object.hasOwn(submitted, "ticketSessions")
|
|
875
|
+
? projectDiaristSessions(parameters)
|
|
876
|
+
: undefined;
|
|
877
|
+
const ticketSessions = submitted && Object.hasOwn(submitted, "ticketSessions")
|
|
878
|
+
? projectDiaristTicketSessions(submitted)
|
|
879
|
+
: singleSessions === undefined
|
|
880
|
+
? undefined
|
|
881
|
+
: [{ ticketNumber: ticketNumber ?? null, sessions: singleSessions }];
|
|
882
|
+
if (ticketSessions === undefined) {
|
|
875
883
|
throw new ParentQueueReaskError(DIARIST_BOUNDS_REASK);
|
|
876
884
|
}
|
|
877
|
-
let facts;
|
|
878
885
|
try {
|
|
879
|
-
|
|
880
|
-
ticketNumber: ticketNumber ?? null,
|
|
886
|
+
await commitDiaristProjection({
|
|
881
887
|
cwd: coords.projectRoot,
|
|
882
888
|
home: coords.home,
|
|
883
889
|
runDirectory: coords.runDirectory,
|
|
884
|
-
|
|
890
|
+
tickets: ticketSessions,
|
|
885
891
|
});
|
|
886
892
|
} catch (error) {
|
|
887
893
|
// Bound/session input failures → reask via typed identity (not message prefix).
|
package/src/ticket-provenance.ts
CHANGED
|
@@ -162,11 +162,6 @@ export async function rehomeUnboundTicketProvenance(
|
|
|
162
162
|
await unlink(source);
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
export type ReprojectTicketProvenanceResult = {
|
|
166
|
-
readonly recordFile: string;
|
|
167
|
-
readonly lines: readonly TicketProvenanceLine[];
|
|
168
|
-
};
|
|
169
|
-
|
|
170
165
|
/**
|
|
171
166
|
* Resolve a bound endpoint against this round's session lines.
|
|
172
167
|
* id → first physical line carrying that native id; line → that 1-based line.
|
|
@@ -327,53 +322,45 @@ async function projectSessionRanges(input: {
|
|
|
327
322
|
}
|
|
328
323
|
|
|
329
324
|
/**
|
|
330
|
-
*
|
|
325
|
+
* Project every submitted boundary before appending any ticket's record.
|
|
331
326
|
* #1090: 纯追加——不回读已成录历史查重、不折叠、不刷新;同一区间再次提交也留下新的追加记录。
|
|
332
327
|
* 证不出的 body 原字节原样留卷。
|
|
333
328
|
*/
|
|
334
|
-
export async function
|
|
335
|
-
readonly ticketNumber: number | null;
|
|
329
|
+
export async function reprojectTicketProvenanceBatch(input: {
|
|
336
330
|
readonly cwd: string;
|
|
337
331
|
readonly home?: string;
|
|
338
332
|
readonly runDirectory?: string;
|
|
339
|
-
readonly
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
333
|
+
readonly tickets: readonly {
|
|
334
|
+
readonly ticketNumber: number | null;
|
|
335
|
+
readonly sessions: readonly TicketProvenanceSession[];
|
|
336
|
+
}[];
|
|
337
|
+
}): Promise<void> {
|
|
338
|
+
const projections = [];
|
|
339
|
+
for (const ticket of input.tickets) {
|
|
340
|
+
const recordInput = ticketProvenanceRecordInput(
|
|
341
|
+
ticket.ticketNumber, input.cwd, input.home, input.runDirectory,
|
|
342
|
+
);
|
|
343
|
+
const entries: (TicketProvenanceLine | TicketProvenanceRaw)[] = [];
|
|
344
|
+
for (let s = 0; s < ticket.sessions.length; s += 1) {
|
|
345
|
+
const projected = await projectSessionRanges({
|
|
346
|
+
s,
|
|
347
|
+
session: ticket.sessions[s]!,
|
|
348
|
+
...(input.home === undefined ? {} : { home: input.home }),
|
|
349
|
+
});
|
|
350
|
+
entries.push(...projected.entries);
|
|
351
|
+
}
|
|
352
|
+
projections.push({ ticket, recordInput, entries });
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
-
const entries
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
355
|
+
for (const { ticket, recordInput, entries } of projections) {
|
|
356
|
+
if (ticket.sessions.length === 0) continue;
|
|
357
|
+
appendSitianRecord({
|
|
358
|
+
...recordInput,
|
|
359
|
+
payload: {
|
|
360
|
+
type: "ticket-provenance-append",
|
|
361
|
+
sessions: ticket.sessions,
|
|
362
|
+
lines: entries,
|
|
363
|
+
},
|
|
362
364
|
});
|
|
363
|
-
entries.push(...projected.entries);
|
|
364
365
|
}
|
|
365
|
-
|
|
366
|
-
const pointer = appendSitianRecord({
|
|
367
|
-
...recordInput,
|
|
368
|
-
payload: {
|
|
369
|
-
type: "ticket-provenance-append",
|
|
370
|
-
sessions: input.sessions,
|
|
371
|
-
lines: entries,
|
|
372
|
-
},
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
return {
|
|
376
|
-
recordFile: pointer.recordFile,
|
|
377
|
-
lines: entries.filter((entry): entry is TicketProvenanceLine => "speaker" in entry),
|
|
378
|
-
};
|
|
379
366
|
}
|