@akagilnc/pi-workflow-roles 0.1.4204 → 0.1.4228
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 +1203 -770
- package/dist/atomic-write.js +23 -0
- package/dist/diarist-contracts.js +22 -8
- package/dist/headless-host/production-host.js +1191 -758
- package/dist/ledger-session-read.js +52 -21
- package/dist/migrate-book-topology.js +238 -205
- package/dist/public-cli/case-dossier-delivery.js +0 -1
- package/dist/public-cli/main.js +303 -261
- package/dist/session-dialogue.js +221 -0
- package/dist/sitian-facade.js +1 -0
- package/dist/sitian-volume.js +67 -0
- package/dist/ticket-provenance-contracts.js +122 -39
- package/dist/ticket-provenance.js +289 -204
- package/package.json +1 -1
- package/src/book-topology-migration.ts +0 -7
- package/src/book-topology-record-class-migrators.ts +203 -99
- package/src/diarist-contracts.ts +42 -29
- package/src/diarist-role.ts +77 -31
- package/src/diarist.ts +31 -67
- package/src/ledger-session-read.ts +70 -27
- package/src/package-contracts/reviewer-output.ts +1 -1
- package/src/public-cli/case-dossier-delivery.ts +0 -1
- package/src/reviewer-role.ts +3 -3
- package/src/role-runtime.ts +56 -14
- package/src/session-dialogue.ts +225 -0
- package/src/sitian-appender.ts +1 -1
- package/src/sitian-facade.ts +7 -1
- package/src/sitian-volume.ts +91 -0
- package/src/ticket-provenance-contracts.ts +158 -101
- package/src/ticket-provenance.ts +387 -263
|
@@ -206,10 +206,75 @@ var init_collector_config = __esm({
|
|
|
206
206
|
}
|
|
207
207
|
});
|
|
208
208
|
|
|
209
|
+
// src/ticket-provenance-contracts.ts
|
|
210
|
+
function isRecord(value2) {
|
|
211
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
212
|
+
}
|
|
213
|
+
function positiveInteger(value2) {
|
|
214
|
+
if (typeof value2 === "number" && Number.isSafeInteger(value2) && value2 >= 1) return value2;
|
|
215
|
+
if (typeof value2 === "string" && /^[1-9][0-9]*$/.test(value2)) {
|
|
216
|
+
const parsed = Number(value2);
|
|
217
|
+
if (Number.isSafeInteger(parsed)) return parsed;
|
|
218
|
+
}
|
|
219
|
+
return void 0;
|
|
220
|
+
}
|
|
221
|
+
function projectBound(value2) {
|
|
222
|
+
if (!isRecord(value2)) return void 0;
|
|
223
|
+
const id = typeof value2.id === "string" && value2.id !== "" ? value2.id : void 0;
|
|
224
|
+
const line = positiveInteger(value2.line);
|
|
225
|
+
if (id === void 0 && line === void 0) return void 0;
|
|
226
|
+
return { ...id === void 0 ? {} : { id }, ...line === void 0 ? {} : { line } };
|
|
227
|
+
}
|
|
228
|
+
function projectTicketProvenanceSessions(value2) {
|
|
229
|
+
if (!Array.isArray(value2)) return void 0;
|
|
230
|
+
if (value2.length === 0) return [];
|
|
231
|
+
const sessions = [];
|
|
232
|
+
for (const raw of value2) {
|
|
233
|
+
if (!isRecord(raw)) return void 0;
|
|
234
|
+
const path7 = raw.path;
|
|
235
|
+
if (typeof path7 !== "string" || path7.trim() === "") return void 0;
|
|
236
|
+
if (!Array.isArray(raw.ranges) || raw.ranges.length === 0) return void 0;
|
|
237
|
+
const ranges = [];
|
|
238
|
+
for (const rawRange of raw.ranges) {
|
|
239
|
+
if (!isRecord(rawRange)) return void 0;
|
|
240
|
+
const from = projectBound(rawRange.from);
|
|
241
|
+
const to = projectBound(rawRange.to);
|
|
242
|
+
if (from === void 0 || to === void 0) return void 0;
|
|
243
|
+
ranges.push({ from, to });
|
|
244
|
+
}
|
|
245
|
+
sessions.push({ path: path7, ranges });
|
|
246
|
+
}
|
|
247
|
+
return sessions;
|
|
248
|
+
}
|
|
249
|
+
function projectTicketProvenanceHeader(value2) {
|
|
250
|
+
if (!isRecord(value2)) return void 0;
|
|
251
|
+
const ticket = positiveInteger(value2.ticket);
|
|
252
|
+
if (ticket === void 0) return void 0;
|
|
253
|
+
if (typeof value2.repo !== "string") return void 0;
|
|
254
|
+
if (typeof value2.createdAt !== "string" || typeof value2.updatedAt !== "string") {
|
|
255
|
+
return void 0;
|
|
256
|
+
}
|
|
257
|
+
const sessions = projectTicketProvenanceSessions(value2.sessions);
|
|
258
|
+
if (sessions === void 0) return void 0;
|
|
259
|
+
return {
|
|
260
|
+
repo: value2.repo,
|
|
261
|
+
ticket,
|
|
262
|
+
createdAt: value2.createdAt,
|
|
263
|
+
updatedAt: value2.updatedAt,
|
|
264
|
+
sessions
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
var init_ticket_provenance_contracts = __esm({
|
|
268
|
+
"src/ticket-provenance-contracts.ts"() {
|
|
269
|
+
"use strict";
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
|
|
209
273
|
// src/diarist-contracts.ts
|
|
210
274
|
var init_diarist_contracts = __esm({
|
|
211
275
|
"src/diarist-contracts.ts"() {
|
|
212
276
|
"use strict";
|
|
277
|
+
init_ticket_provenance_contracts();
|
|
213
278
|
init_run_ticket_number();
|
|
214
279
|
}
|
|
215
280
|
});
|
|
@@ -254377,129 +254442,6 @@ var init_sitian_appender = __esm({
|
|
|
254377
254442
|
}
|
|
254378
254443
|
});
|
|
254379
254444
|
|
|
254380
|
-
// src/ticket-provenance-contracts.ts
|
|
254381
|
-
function isRecord3(value2) {
|
|
254382
|
-
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
254383
|
-
}
|
|
254384
|
-
function projectTicketProvenanceEntry(value2) {
|
|
254385
|
-
if (!isRecord3(value2)) return void 0;
|
|
254386
|
-
if (value2.recordClass === TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
|
|
254387
|
-
return void 0;
|
|
254388
|
-
}
|
|
254389
|
-
if (typeof value2.sourceKind !== "string" || typeof value2.transcript !== "string") {
|
|
254390
|
-
return void 0;
|
|
254391
|
-
}
|
|
254392
|
-
return value2;
|
|
254393
|
-
}
|
|
254394
|
-
var TICKET_PROVENANCE_HUMAN_VIEW, TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC;
|
|
254395
|
-
var init_ticket_provenance_contracts = __esm({
|
|
254396
|
-
"src/ticket-provenance-contracts.ts"() {
|
|
254397
|
-
"use strict";
|
|
254398
|
-
TICKET_PROVENANCE_HUMAN_VIEW = "\u8D77\u5C45\u5F55.md";
|
|
254399
|
-
TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC = "diagnostic";
|
|
254400
|
-
}
|
|
254401
|
-
});
|
|
254402
|
-
|
|
254403
|
-
// src/sitian-reader.ts
|
|
254404
|
-
var init_sitian_reader = __esm({
|
|
254405
|
-
"src/sitian-reader.ts"() {
|
|
254406
|
-
"use strict";
|
|
254407
|
-
}
|
|
254408
|
-
});
|
|
254409
|
-
|
|
254410
|
-
// src/sitian-facade.ts
|
|
254411
|
-
var init_sitian_facade = __esm({
|
|
254412
|
-
"src/sitian-facade.ts"() {
|
|
254413
|
-
"use strict";
|
|
254414
|
-
init_sitian_appender();
|
|
254415
|
-
init_sitian_contracts();
|
|
254416
|
-
init_sitian_appender();
|
|
254417
|
-
init_sitian_reader();
|
|
254418
|
-
}
|
|
254419
|
-
});
|
|
254420
|
-
|
|
254421
|
-
// src/ticket-provenance.ts
|
|
254422
|
-
function markdownFenceFor(text) {
|
|
254423
|
-
let longest = 0;
|
|
254424
|
-
const runs = text.match(/`+/g);
|
|
254425
|
-
if (runs !== null) {
|
|
254426
|
-
for (const run of runs) {
|
|
254427
|
-
if (run.length > longest) longest = run.length;
|
|
254428
|
-
}
|
|
254429
|
-
}
|
|
254430
|
-
return "`".repeat(Math.max(3, longest + 1));
|
|
254431
|
-
}
|
|
254432
|
-
function renderTicketProvenanceMarkdown(input) {
|
|
254433
|
-
const unprojected = input.unprojected ?? [];
|
|
254434
|
-
const lines = [
|
|
254435
|
-
`# \u8D77\u5C45\u5F55 \xB7 #${input.ticketNumber}`,
|
|
254436
|
-
"",
|
|
254437
|
-
`\u6761\u76EE\u6570\uFF1A${input.entries.length + unprojected.length}`,
|
|
254438
|
-
""
|
|
254439
|
-
];
|
|
254440
|
-
let index3 = 0;
|
|
254441
|
-
for (const entry of input.entries) {
|
|
254442
|
-
index3 += 1;
|
|
254443
|
-
const sourceKind = typeof entry.sourceKind === "string" ? entry.sourceKind : "\u672A\u6295\u5F71";
|
|
254444
|
-
const timestamp = typeof entry.timestamp === "string" ? entry.timestamp : "";
|
|
254445
|
-
lines.push(`## ${index3}. ${sourceKind} \xB7 ${timestamp}`);
|
|
254446
|
-
lines.push("");
|
|
254447
|
-
const basis = entry.basis;
|
|
254448
|
-
const method = typeof basis === "object" && basis !== null && !Array.isArray(basis) && typeof basis.method === "string" ? basis.method : "\u672A\u6295\u5F71";
|
|
254449
|
-
lines.push(`- basis.method: \`${method}\``);
|
|
254450
|
-
if (typeof basis === "object" && basis !== null && !Array.isArray(basis) && Array.isArray(basis.anchors) && basis.anchors.length > 0) {
|
|
254451
|
-
lines.push(`- anchors: ${basis.anchors.map((a) => `\`${String(a)}\``).join(", ")}`);
|
|
254452
|
-
}
|
|
254453
|
-
if (typeof basis === "object" && basis !== null && !Array.isArray(basis) && basis.note !== void 0) {
|
|
254454
|
-
lines.push(`- note: ${String(basis.note)}`);
|
|
254455
|
-
}
|
|
254456
|
-
const sourceRef = typeof entry.sourceRef === "object" && entry.sourceRef !== null && !Array.isArray(entry.sourceRef) ? entry.sourceRef : {};
|
|
254457
|
-
const refParts = [];
|
|
254458
|
-
if (sourceRef.sessionFile !== void 0) {
|
|
254459
|
-
refParts.push(`sessionFile=${String(sourceRef.sessionFile)}`);
|
|
254460
|
-
}
|
|
254461
|
-
if (sourceRef.entryId !== void 0) {
|
|
254462
|
-
refParts.push(`entryId=${String(sourceRef.entryId)}`);
|
|
254463
|
-
}
|
|
254464
|
-
if (sourceRef.path !== void 0) {
|
|
254465
|
-
refParts.push(`path=${String(sourceRef.path)}`);
|
|
254466
|
-
}
|
|
254467
|
-
if (sourceRef.url !== void 0) {
|
|
254468
|
-
refParts.push(`url=${String(sourceRef.url)}`);
|
|
254469
|
-
}
|
|
254470
|
-
if (refParts.length > 0) {
|
|
254471
|
-
lines.push(`- sourceRef: ${refParts.join(" \xB7 ")}`);
|
|
254472
|
-
}
|
|
254473
|
-
lines.push("");
|
|
254474
|
-
const transcript = typeof entry.transcript === "string" ? entry.transcript : JSON.stringify(entry);
|
|
254475
|
-
const fence = markdownFenceFor(transcript);
|
|
254476
|
-
lines.push(fence);
|
|
254477
|
-
lines.push(transcript);
|
|
254478
|
-
lines.push(fence);
|
|
254479
|
-
lines.push("");
|
|
254480
|
-
}
|
|
254481
|
-
for (const payload of unprojected) {
|
|
254482
|
-
index3 += 1;
|
|
254483
|
-
lines.push(`## ${index3}. \u672A\u6295\u5F71`);
|
|
254484
|
-
lines.push("");
|
|
254485
|
-
const text = typeof payload === "string" ? payload : JSON.stringify(payload);
|
|
254486
|
-
const fence = markdownFenceFor(text);
|
|
254487
|
-
lines.push(fence);
|
|
254488
|
-
lines.push(text);
|
|
254489
|
-
lines.push(fence);
|
|
254490
|
-
lines.push("");
|
|
254491
|
-
}
|
|
254492
|
-
return lines.join("\n");
|
|
254493
|
-
}
|
|
254494
|
-
var init_ticket_provenance = __esm({
|
|
254495
|
-
"src/ticket-provenance.ts"() {
|
|
254496
|
-
"use strict";
|
|
254497
|
-
init_sitian_facade();
|
|
254498
|
-
init_run_ticket_number();
|
|
254499
|
-
init_ticket_provenance_contracts();
|
|
254500
|
-
}
|
|
254501
|
-
});
|
|
254502
|
-
|
|
254503
254445
|
// scripts/migrate-book-topology.ts
|
|
254504
254446
|
import { resolve as resolve8 } from "node:path";
|
|
254505
254447
|
|
|
@@ -254596,8 +254538,7 @@ async function migrateBookTopology(input) {
|
|
|
254596
254538
|
await mkdir(booksDirectory);
|
|
254597
254539
|
const context2 = {
|
|
254598
254540
|
backupBooksDirectory,
|
|
254599
|
-
booksDirectory
|
|
254600
|
-
touchedTicketsByBook: /* @__PURE__ */ new Map()
|
|
254541
|
+
booksDirectory
|
|
254601
254542
|
};
|
|
254602
254543
|
const partitions = [];
|
|
254603
254544
|
for (const migrator of input.migrators) {
|
|
@@ -276895,7 +276836,7 @@ import { readdir as readdir4, readFile as readFile4 } from "node:fs/promises";
|
|
|
276895
276836
|
import { basename as basename6, dirname as dirname6, isAbsolute as isAbsolute3, join as join11, relative as relative3, resolve as resolve5, sep as sep6 } from "node:path";
|
|
276896
276837
|
var TICKET_NUMBER_RE = /^[1-9][0-9]*$/;
|
|
276897
276838
|
var RUN_DIR_NAME_RE = /^([^@]+)@([^@]+)$/;
|
|
276898
|
-
function
|
|
276839
|
+
function isRecord2(value2) {
|
|
276899
276840
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
276900
276841
|
}
|
|
276901
276842
|
function isMigrationEnoent(error51) {
|
|
@@ -276941,7 +276882,7 @@ async function readProjectRootFromRun(runDirectory) {
|
|
|
276941
276882
|
const path7 = join11(runDirectory, page);
|
|
276942
276883
|
try {
|
|
276943
276884
|
const raw = JSON.parse(await readFile4(path7, "utf8"));
|
|
276944
|
-
if (!
|
|
276885
|
+
if (!isRecord2(raw)) continue;
|
|
276945
276886
|
const projectRoot = raw.projectRoot;
|
|
276946
276887
|
if (typeof projectRoot === "string" && projectRoot.length > 0) {
|
|
276947
276888
|
return { projectRoot, sourcePage: page };
|
|
@@ -277175,7 +277116,7 @@ function runCoordsFromSessionParent(sessionParent) {
|
|
|
277175
277116
|
}
|
|
277176
277117
|
function runIdFromSubject(subject) {
|
|
277177
277118
|
if (typeof subject === "string" && subject.length > 0) return subject;
|
|
277178
|
-
if (
|
|
277119
|
+
if (isRecord2(subject) && typeof subject.runId === "string" && subject.runId.length > 0) {
|
|
277179
277120
|
return subject.runId;
|
|
277180
277121
|
}
|
|
277181
277122
|
return void 0;
|
|
@@ -277184,7 +277125,7 @@ function ticketNumberFromSubject(subject) {
|
|
|
277184
277125
|
if (typeof subject === "string" || typeof subject === "number") {
|
|
277185
277126
|
return ticketNumberFromUnknown(subject);
|
|
277186
277127
|
}
|
|
277187
|
-
if (
|
|
277128
|
+
if (isRecord2(subject)) return ticketNumberFromUnknown(subject.ticketNumber);
|
|
277188
277129
|
return void 0;
|
|
277189
277130
|
}
|
|
277190
277131
|
|
|
@@ -277196,7 +277137,7 @@ var SITIAN_MIXED_VOLUME_PARTITIONS = [
|
|
|
277196
277137
|
"gate"
|
|
277197
277138
|
];
|
|
277198
277139
|
var CURRENT_SESSION_LEDGER = "current-session.json";
|
|
277199
|
-
function
|
|
277140
|
+
function isRecord3(value2) {
|
|
277200
277141
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
277201
277142
|
}
|
|
277202
277143
|
function posixRelative(from, to) {
|
|
@@ -277212,17 +277153,17 @@ function pathCandidatesFromRecord(record2) {
|
|
|
277212
277153
|
const seen = /* @__PURE__ */ new Set();
|
|
277213
277154
|
addPathCandidate(paths, seen, record2.sessionParent);
|
|
277214
277155
|
addPathCandidate(paths, seen, record2.parentSession);
|
|
277215
|
-
if (!
|
|
277156
|
+
if (!isRecord3(record2.payload)) return paths;
|
|
277216
277157
|
const payload = record2.payload;
|
|
277217
277158
|
addPathCandidate(paths, seen, payload.sessionParent);
|
|
277218
277159
|
addPathCandidate(paths, seen, payload.parentSession);
|
|
277219
277160
|
addPathCandidate(paths, seen, payload.sessionFile);
|
|
277220
|
-
if (
|
|
277161
|
+
if (isRecord3(payload.parent)) {
|
|
277221
277162
|
addPathCandidate(paths, seen, payload.parent.sessionFile);
|
|
277222
277163
|
addPathCandidate(paths, seen, payload.parent.sessionParent);
|
|
277223
277164
|
addPathCandidate(paths, seen, payload.parent.parentSession);
|
|
277224
277165
|
}
|
|
277225
|
-
if (
|
|
277166
|
+
if (isRecord3(payload.data)) {
|
|
277226
277167
|
addPathCandidate(paths, seen, payload.data.sessionParent);
|
|
277227
277168
|
addPathCandidate(paths, seen, payload.data.parentSession);
|
|
277228
277169
|
addPathCandidate(paths, seen, payload.data.sessionFile);
|
|
@@ -277277,7 +277218,7 @@ function inspectWorkerSubmissionGateVolume(text, bookRoots) {
|
|
|
277277
277218
|
malformedRows.push({ lineNumber: row.lineNumber, raw: row.raw });
|
|
277278
277219
|
continue;
|
|
277279
277220
|
}
|
|
277280
|
-
if (!
|
|
277221
|
+
if (!isRecord3(parsed)) {
|
|
277281
277222
|
malformedRows.push({ lineNumber: row.lineNumber, raw: row.raw });
|
|
277282
277223
|
continue;
|
|
277283
277224
|
}
|
|
@@ -277330,7 +277271,7 @@ async function migrateCurrentSessionPointer(input) {
|
|
|
277330
277271
|
let sessionFile;
|
|
277331
277272
|
try {
|
|
277332
277273
|
const parsed = JSON.parse(raw);
|
|
277333
|
-
if (
|
|
277274
|
+
if (isRecord3(parsed) && typeof parsed.sessionFile === "string" && parsed.sessionFile.length > 0) {
|
|
277334
277275
|
sessionFile = parsed.sessionFile;
|
|
277335
277276
|
}
|
|
277336
277277
|
} catch {
|
|
@@ -277408,7 +277349,7 @@ async function migrateSitianMixedVolume(partition4, context2) {
|
|
|
277408
277349
|
});
|
|
277409
277350
|
continue;
|
|
277410
277351
|
}
|
|
277411
|
-
if (!
|
|
277352
|
+
if (!isRecord3(parsed)) {
|
|
277412
277353
|
const dest2 = volumeDestinationFile(
|
|
277413
277354
|
booksDirectory,
|
|
277414
277355
|
bookKey,
|
|
@@ -278180,19 +278121,10 @@ import { appendFile as appendFile2, mkdir as mkdir4, readFile as readFile7, stat
|
|
|
278180
278121
|
import { dirname as dirname9, join as join14, relative as relative6, sep as sep9 } from "node:path";
|
|
278181
278122
|
init_sitian_appender();
|
|
278182
278123
|
init_ticket_provenance_contracts();
|
|
278183
|
-
init_ticket_provenance();
|
|
278184
278124
|
var TICKET_PROVENANCE = "ticket-provenance";
|
|
278185
278125
|
var SUBMISSION_LEDGER = "submission-ledger";
|
|
278186
278126
|
var ATTEMPT_HISTORY = "attempt-history";
|
|
278187
278127
|
var MISPLACED = "misplaced-record-class";
|
|
278188
|
-
function noteTouchedTicket(context2, bookKey, ticketNumber) {
|
|
278189
|
-
let set2 = context2.touchedTicketsByBook.get(bookKey);
|
|
278190
|
-
if (set2 === void 0) {
|
|
278191
|
-
set2 = /* @__PURE__ */ new Set();
|
|
278192
|
-
context2.touchedTicketsByBook.set(bookKey, set2);
|
|
278193
|
-
}
|
|
278194
|
-
set2.add(ticketNumber);
|
|
278195
|
-
}
|
|
278196
278128
|
function isRecord4(value2) {
|
|
278197
278129
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
278198
278130
|
}
|
|
@@ -278232,6 +278164,10 @@ async function ensureDir(path7) {
|
|
|
278232
278164
|
}
|
|
278233
278165
|
var RecordWriteCache = class {
|
|
278234
278166
|
identities = /* @__PURE__ */ new Map();
|
|
278167
|
+
/** Dest paths written as whole #901 bare volumes — legacy must not append under them. */
|
|
278168
|
+
bareVolumeFiles = /* @__PURE__ */ new Set();
|
|
278169
|
+
/** Lines currently on a dest that are still claimed `placed` in outcomes. */
|
|
278170
|
+
destPlacements = /* @__PURE__ */ new Map();
|
|
278235
278171
|
async load(recordFile) {
|
|
278236
278172
|
const cached2 = this.identities.get(recordFile);
|
|
278237
278173
|
if (cached2 !== void 0) return cached2;
|
|
@@ -278244,19 +278180,66 @@ var RecordWriteCache = class {
|
|
|
278244
278180
|
this.identities.set(recordFile, set2);
|
|
278245
278181
|
return set2;
|
|
278246
278182
|
}
|
|
278247
|
-
|
|
278183
|
+
markBareVolume(recordFile) {
|
|
278184
|
+
this.bareVolumeFiles.add(recordFile);
|
|
278185
|
+
this.identities.set(recordFile, /* @__PURE__ */ new Set());
|
|
278186
|
+
}
|
|
278187
|
+
isBareVolume(recordFile) {
|
|
278188
|
+
return this.bareVolumeFiles.has(recordFile);
|
|
278189
|
+
}
|
|
278190
|
+
/**
|
|
278191
|
+
* After a bare whole-file write, register its lines so a later bare for the
|
|
278192
|
+
* same ticket can rehome them and flip dispositions (multi-bare honesty).
|
|
278193
|
+
*/
|
|
278194
|
+
setDestPlacements(recordFile, placements) {
|
|
278195
|
+
this.destPlacements.set(recordFile, [...placements]);
|
|
278196
|
+
}
|
|
278197
|
+
/**
|
|
278198
|
+
* Install a bare volume as the sole ticket file. Any lines already placed on
|
|
278199
|
+
* this dest (legacy appends or a prior bare) are moved to unbound and their
|
|
278200
|
+
* outcomes flipped — report stays honest.
|
|
278201
|
+
*/
|
|
278202
|
+
async replaceWholeBare(recordFile, body, outcomes, unboundFileForRaw) {
|
|
278203
|
+
const prior = this.destPlacements.get(recordFile) ?? [];
|
|
278204
|
+
for (const placement of prior) {
|
|
278205
|
+
await this.append(unboundFileForRaw(placement.raw), placement.raw);
|
|
278206
|
+
const previous = outcomes[placement.outcomeIndex];
|
|
278207
|
+
if (previous !== void 0) {
|
|
278208
|
+
outcomes[placement.outcomeIndex] = {
|
|
278209
|
+
disposition: "unbound",
|
|
278210
|
+
source: previous.source
|
|
278211
|
+
};
|
|
278212
|
+
}
|
|
278213
|
+
}
|
|
278214
|
+
this.destPlacements.delete(recordFile);
|
|
278215
|
+
await ensureDir(dirname9(recordFile));
|
|
278216
|
+
const text = body.endsWith("\n") ? body : `${body}
|
|
278217
|
+
`;
|
|
278218
|
+
await writeFile6(recordFile, text, "utf8");
|
|
278219
|
+
this.markBareVolume(recordFile);
|
|
278220
|
+
}
|
|
278221
|
+
async append(recordFile, raw, options) {
|
|
278248
278222
|
await ensureDir(dirname9(recordFile));
|
|
278249
278223
|
const line = raw.endsWith("\n") ? raw : `${raw}
|
|
278250
278224
|
`;
|
|
278251
278225
|
const parsed = parseJsonlLine(raw);
|
|
278252
278226
|
if (parsed.ok && typeof parsed.value.identity === "string") {
|
|
278253
278227
|
const existing = await this.load(recordFile);
|
|
278254
|
-
if (existing.has(parsed.value.identity))
|
|
278255
|
-
|
|
278256
|
-
|
|
278257
|
-
|
|
278228
|
+
if (!existing.has(parsed.value.identity)) {
|
|
278229
|
+
existing.add(parsed.value.identity);
|
|
278230
|
+
await appendFile2(recordFile, line, "utf8");
|
|
278231
|
+
}
|
|
278232
|
+
} else {
|
|
278233
|
+
if (!this.identities.has(recordFile)) {
|
|
278234
|
+
this.identities.set(recordFile, await this.load(recordFile));
|
|
278235
|
+
}
|
|
278236
|
+
await appendFile2(recordFile, line, "utf8");
|
|
278237
|
+
}
|
|
278238
|
+
if (options?.outcomeIndex !== void 0 && !this.bareVolumeFiles.has(recordFile)) {
|
|
278239
|
+
const list = this.destPlacements.get(recordFile) ?? [];
|
|
278240
|
+
list.push({ raw, outcomeIndex: options.outcomeIndex });
|
|
278241
|
+
this.destPlacements.set(recordFile, list);
|
|
278258
278242
|
}
|
|
278259
|
-
await appendFile2(recordFile, line, "utf8");
|
|
278260
278243
|
}
|
|
278261
278244
|
};
|
|
278262
278245
|
function roleFromPayload(payload) {
|
|
@@ -278392,7 +278375,7 @@ async function resolveRunDestination(context2, bookKey, runId, hints) {
|
|
|
278392
278375
|
}
|
|
278393
278376
|
return { kind: "unbound-key", key: stableKey(runId) };
|
|
278394
278377
|
}
|
|
278395
|
-
async function placeTicketProvenanceLine(context2, bookKey, writes, source, raw, value2) {
|
|
278378
|
+
async function placeTicketProvenanceLine(context2, bookKey, writes, source, raw, value2, outcomeIndex) {
|
|
278396
278379
|
if (value2 === void 0) {
|
|
278397
278380
|
await writes.append(unboundCategoryFile(context2.booksDirectory, bookKey, TICKET_PROVENANCE, stableKey(raw)), raw);
|
|
278398
278381
|
return { disposition: "unbound", source, malformed: true, malformedRaw: raw };
|
|
@@ -278402,11 +278385,29 @@ async function placeTicketProvenanceLine(context2, bookKey, writes, source, raw,
|
|
|
278402
278385
|
await writes.append(unboundCategoryFile(context2.booksDirectory, bookKey, TICKET_PROVENANCE, stableKey(raw)), raw);
|
|
278403
278386
|
return { disposition: "unbound", source };
|
|
278404
278387
|
}
|
|
278405
|
-
|
|
278406
|
-
|
|
278407
|
-
|
|
278388
|
+
const dest = join14(
|
|
278389
|
+
context2.booksDirectory,
|
|
278390
|
+
bookKey,
|
|
278391
|
+
String(ticketNumber),
|
|
278392
|
+
"records.jsonl"
|
|
278408
278393
|
);
|
|
278409
|
-
|
|
278394
|
+
if (writes.isBareVolume(dest)) {
|
|
278395
|
+
await writes.append(
|
|
278396
|
+
unboundCategoryFile(context2.booksDirectory, bookKey, TICKET_PROVENANCE, stableKey(raw)),
|
|
278397
|
+
raw
|
|
278398
|
+
);
|
|
278399
|
+
return { disposition: "unbound", source };
|
|
278400
|
+
}
|
|
278401
|
+
const existing = await readJsonlLines(dest);
|
|
278402
|
+
if (tryBareTicketProvenanceVolume(existing) !== void 0) {
|
|
278403
|
+
writes.markBareVolume(dest);
|
|
278404
|
+
await writes.append(
|
|
278405
|
+
unboundCategoryFile(context2.booksDirectory, bookKey, TICKET_PROVENANCE, stableKey(raw)),
|
|
278406
|
+
raw
|
|
278407
|
+
);
|
|
278408
|
+
return { disposition: "unbound", source };
|
|
278409
|
+
}
|
|
278410
|
+
await writes.append(dest, raw, { outcomeIndex });
|
|
278410
278411
|
return { disposition: "placed", source };
|
|
278411
278412
|
}
|
|
278412
278413
|
async function placeRunOwnedLine(context2, bookKey, writes, category, source, raw, value2) {
|
|
@@ -278432,10 +278433,10 @@ async function placeRunOwnedLine(context2, bookKey, writes, category, source, ra
|
|
|
278432
278433
|
await writes.append(join14(target.runDirectory, "session", category, "records.jsonl"), raw);
|
|
278433
278434
|
return { disposition: target.disposition, source };
|
|
278434
278435
|
}
|
|
278435
|
-
async function placeRecordClassLine(context2, bookKey, writes, source, raw, value2, fallbackCategory) {
|
|
278436
|
+
async function placeRecordClassLine(context2, bookKey, writes, source, raw, value2, fallbackCategory, outcomeIndex) {
|
|
278436
278437
|
const recordClass = recordClassOfKind(value2.kind);
|
|
278437
278438
|
if (recordClass === TICKET_PROVENANCE) {
|
|
278438
|
-
return placeTicketProvenanceLine(context2, bookKey, writes, source, raw, value2);
|
|
278439
|
+
return placeTicketProvenanceLine(context2, bookKey, writes, source, raw, value2, outcomeIndex);
|
|
278439
278440
|
}
|
|
278440
278441
|
if (recordClass === SUBMISSION_LEDGER || recordClass === ATTEMPT_HISTORY) {
|
|
278441
278442
|
return placeRunOwnedLine(context2, bookKey, writes, recordClass, source, raw, value2);
|
|
@@ -278446,8 +278447,53 @@ async function placeRecordClassLine(context2, bookKey, writes, source, raw, valu
|
|
|
278446
278447
|
);
|
|
278447
278448
|
return { disposition: "unbound", source };
|
|
278448
278449
|
}
|
|
278450
|
+
function tryBareTicketProvenanceVolume(lines) {
|
|
278451
|
+
const body = [];
|
|
278452
|
+
for (const raw of lines) {
|
|
278453
|
+
if (raw.trim() === "") continue;
|
|
278454
|
+
body.push(raw);
|
|
278455
|
+
}
|
|
278456
|
+
if (body.length === 0) return void 0;
|
|
278457
|
+
const first = parseJsonlLine(body[0]);
|
|
278458
|
+
if (!first.ok) return void 0;
|
|
278459
|
+
if (recordClassOfKind(first.value.kind) !== void 0) return void 0;
|
|
278460
|
+
const header = projectTicketProvenanceHeader(first.value);
|
|
278461
|
+
if (header === void 0) return void 0;
|
|
278462
|
+
return { ticket: header.ticket, body };
|
|
278463
|
+
}
|
|
278464
|
+
async function placeBareTicketProvenanceVolume(context2, bookKey, writes, filePath, bare, outcomes) {
|
|
278465
|
+
const dest = join14(
|
|
278466
|
+
context2.booksDirectory,
|
|
278467
|
+
bookKey,
|
|
278468
|
+
String(bare.ticket),
|
|
278469
|
+
"records.jsonl"
|
|
278470
|
+
);
|
|
278471
|
+
const body = bare.body.map((raw) => raw.endsWith("\n") ? raw : `${raw}
|
|
278472
|
+
`).join("");
|
|
278473
|
+
await writes.replaceWholeBare(
|
|
278474
|
+
dest,
|
|
278475
|
+
body,
|
|
278476
|
+
outcomes,
|
|
278477
|
+
(raw) => unboundCategoryFile(context2.booksDirectory, bookKey, TICKET_PROVENANCE, stableKey(raw))
|
|
278478
|
+
);
|
|
278479
|
+
const barePlacements = [];
|
|
278480
|
+
for (let index3 = 0; index3 < bare.body.length; index3 += 1) {
|
|
278481
|
+
const source = lineSource(context2.backupBooksDirectory, filePath, index3);
|
|
278482
|
+
const outcomeIndex = outcomes.length;
|
|
278483
|
+
outcomes.push({ disposition: "placed", source });
|
|
278484
|
+
barePlacements.push({ raw: bare.body[index3], outcomeIndex });
|
|
278485
|
+
}
|
|
278486
|
+
writes.setDestPlacements(dest, barePlacements);
|
|
278487
|
+
}
|
|
278449
278488
|
async function migrateJsonlFileByKind(context2, bookKey, writes, filePath, fallbackCategory, outcomes) {
|
|
278450
278489
|
const lines = await readJsonlLines(filePath);
|
|
278490
|
+
if (fallbackCategory === TICKET_PROVENANCE) {
|
|
278491
|
+
const bare = tryBareTicketProvenanceVolume(lines);
|
|
278492
|
+
if (bare !== void 0) {
|
|
278493
|
+
await placeBareTicketProvenanceVolume(context2, bookKey, writes, filePath, bare, outcomes);
|
|
278494
|
+
return;
|
|
278495
|
+
}
|
|
278496
|
+
}
|
|
278451
278497
|
for (let index3 = 0; index3 < lines.length; index3 += 1) {
|
|
278452
278498
|
const raw = lines[index3];
|
|
278453
278499
|
if (raw.trim() === "") continue;
|
|
@@ -278455,14 +278501,33 @@ async function migrateJsonlFileByKind(context2, bookKey, writes, filePath, fallb
|
|
|
278455
278501
|
const parsed = parseJsonlLine(raw);
|
|
278456
278502
|
if (!parsed.ok) {
|
|
278457
278503
|
if (fallbackCategory === TICKET_PROVENANCE) {
|
|
278458
|
-
outcomes.push(
|
|
278504
|
+
outcomes.push(
|
|
278505
|
+
await placeTicketProvenanceLine(
|
|
278506
|
+
context2,
|
|
278507
|
+
bookKey,
|
|
278508
|
+
writes,
|
|
278509
|
+
source,
|
|
278510
|
+
raw,
|
|
278511
|
+
void 0,
|
|
278512
|
+
outcomes.length
|
|
278513
|
+
)
|
|
278514
|
+
);
|
|
278459
278515
|
} else {
|
|
278460
278516
|
outcomes.push(await placeRunOwnedLine(context2, bookKey, writes, fallbackCategory, source, raw, void 0));
|
|
278461
278517
|
}
|
|
278462
278518
|
continue;
|
|
278463
278519
|
}
|
|
278464
278520
|
outcomes.push(
|
|
278465
|
-
await placeRecordClassLine(
|
|
278521
|
+
await placeRecordClassLine(
|
|
278522
|
+
context2,
|
|
278523
|
+
bookKey,
|
|
278524
|
+
writes,
|
|
278525
|
+
source,
|
|
278526
|
+
raw,
|
|
278527
|
+
parsed.value,
|
|
278528
|
+
fallbackCategory,
|
|
278529
|
+
outcomes.length
|
|
278530
|
+
)
|
|
278466
278531
|
);
|
|
278467
278532
|
}
|
|
278468
278533
|
}
|
|
@@ -278483,47 +278548,10 @@ async function mergeOfferedIdentities(destDir, volumeDir, writes) {
|
|
|
278483
278548
|
await writes.append(destFile, raw);
|
|
278484
278549
|
}
|
|
278485
278550
|
}
|
|
278486
|
-
async function writeMergedTicketHumanView(destDir, ticketNumber) {
|
|
278487
|
-
const lines = await readJsonlLines(join14(destDir, "records.jsonl"));
|
|
278488
|
-
const entries = [];
|
|
278489
|
-
const unprojected = [];
|
|
278490
|
-
for (const raw of lines) {
|
|
278491
|
-
if (raw.trim() === "") continue;
|
|
278492
|
-
const parsed = parseJsonlLine(raw);
|
|
278493
|
-
if (!parsed.ok) continue;
|
|
278494
|
-
if (recordClassOfKind(parsed.value.kind) !== TICKET_PROVENANCE) continue;
|
|
278495
|
-
const entry = projectTicketProvenanceEntry(parsed.value.payload);
|
|
278496
|
-
if (entry === void 0) {
|
|
278497
|
-
if (parsed.value.payload !== void 0) unprojected.push(parsed.value.payload);
|
|
278498
|
-
continue;
|
|
278499
|
-
}
|
|
278500
|
-
entries.push(entry);
|
|
278501
|
-
}
|
|
278502
|
-
await ensureDir(destDir);
|
|
278503
|
-
await writeFile6(
|
|
278504
|
-
join14(destDir, TICKET_PROVENANCE_HUMAN_VIEW),
|
|
278505
|
-
renderTicketProvenanceMarkdown({
|
|
278506
|
-
ticketNumber,
|
|
278507
|
-
entries,
|
|
278508
|
-
...unprojected.length > 0 ? { unprojected } : {}
|
|
278509
|
-
}),
|
|
278510
|
-
"utf8"
|
|
278511
|
-
);
|
|
278512
|
-
}
|
|
278513
|
-
async function finalizeTicketCompanions(context2, bookKey, ticketNumbers) {
|
|
278514
|
-
for (const ticketNumber of ticketNumbers) {
|
|
278515
|
-
const destDir = join14(context2.booksDirectory, bookKey, String(ticketNumber));
|
|
278516
|
-
try {
|
|
278517
|
-
await stat4(join14(destDir, "records.jsonl"));
|
|
278518
|
-
} catch (error51) {
|
|
278519
|
-
if (isMigrationEnoent(error51)) continue;
|
|
278520
|
-
throw error51;
|
|
278521
|
-
}
|
|
278522
|
-
await writeMergedTicketHumanView(destDir, ticketNumber);
|
|
278523
|
-
}
|
|
278524
|
-
}
|
|
278525
278551
|
async function ticketNumbersInVolume(volumeDir) {
|
|
278526
278552
|
const lines = await readJsonlLines(join14(volumeDir, "records.jsonl"));
|
|
278553
|
+
const bare = tryBareTicketProvenanceVolume(lines);
|
|
278554
|
+
if (bare !== void 0) return [bare.ticket];
|
|
278527
278555
|
const out = [];
|
|
278528
278556
|
const seen = /* @__PURE__ */ new Set();
|
|
278529
278557
|
for (const raw of lines) {
|
|
@@ -278540,7 +278568,6 @@ async function ticketNumbersInVolume(volumeDir) {
|
|
|
278540
278568
|
}
|
|
278541
278569
|
async function mergeCompanionsFromVolume(context2, bookKey, volumeDir, writes) {
|
|
278542
278570
|
for (const ticketNumber of await ticketNumbersInVolume(volumeDir)) {
|
|
278543
|
-
noteTouchedTicket(context2, bookKey, ticketNumber);
|
|
278544
278571
|
const destDir = join14(context2.booksDirectory, bookKey, String(ticketNumber));
|
|
278545
278572
|
await ensureDir(destDir);
|
|
278546
278573
|
await mergeOfferedIdentities(destDir, volumeDir, writes);
|
|
@@ -278572,7 +278599,6 @@ async function migrateHomePartitionBook(context2, bookKey, writes, category, out
|
|
|
278572
278599
|
}
|
|
278573
278600
|
await migrateJsonlFileByKind(context2, bookKey, writes, recordsFile, TICKET_PROVENANCE, outcomes);
|
|
278574
278601
|
await mergeCompanionsFromVolume(context2, bookKey, volumeDir, writes);
|
|
278575
|
-
noteTouchedTicket(context2, bookKey, Number(entry.name));
|
|
278576
278602
|
}
|
|
278577
278603
|
}
|
|
278578
278604
|
}
|
|
@@ -278618,7 +278644,17 @@ async function migrateMisplacedBook(context2, bookKey, writes, outcomes) {
|
|
|
278618
278644
|
if (isAlreadyHomeUnderOwningRun(withinBook, recordClass, parsed.value)) continue;
|
|
278619
278645
|
const source = lineSource(context2.backupBooksDirectory, filePath, index3);
|
|
278620
278646
|
if (recordClass === TICKET_PROVENANCE) {
|
|
278621
|
-
outcomes.push(
|
|
278647
|
+
outcomes.push(
|
|
278648
|
+
await placeTicketProvenanceLine(
|
|
278649
|
+
context2,
|
|
278650
|
+
bookKey,
|
|
278651
|
+
writes,
|
|
278652
|
+
source,
|
|
278653
|
+
raw,
|
|
278654
|
+
parsed.value,
|
|
278655
|
+
outcomes.length
|
|
278656
|
+
)
|
|
278657
|
+
);
|
|
278622
278658
|
} else {
|
|
278623
278659
|
outcomes.push(
|
|
278624
278660
|
await placeRunOwnedLine(context2, bookKey, writes, recordClass, source, raw, parsed.value)
|
|
@@ -278681,9 +278717,6 @@ var misplacedRecordClassPartitionMigrator = {
|
|
|
278681
278717
|
async migrate(context2) {
|
|
278682
278718
|
const outcomes = [];
|
|
278683
278719
|
await forEachBook(context2, (bookKey, writes) => migrateMisplacedBook(context2, bookKey, writes, outcomes));
|
|
278684
|
-
for (const [bookKey, tickets] of context2.touchedTicketsByBook) {
|
|
278685
|
-
await finalizeTicketCompanions(context2, bookKey, tickets);
|
|
278686
|
-
}
|
|
278687
278720
|
return reconcileMigrationPartition(MISPLACED, "lines", outcomes);
|
|
278688
278721
|
}
|
|
278689
278722
|
};
|
|
@@ -40,7 +40,6 @@ export async function projectCaseDossierPointerSection(input) {
|
|
|
40
40
|
CASE_DOSSIER_SECTION_HEADING,
|
|
41
41
|
"",
|
|
42
42
|
`票号:#${input.ticketNumber}`,
|
|
43
|
-
`人读视图:${describeDossierFile(volume.humanViewFile)}`,
|
|
44
43
|
`记录卷宗:${describeDossierFile(volume.recordFile)}`,
|
|
45
44
|
].join("\n");
|
|
46
45
|
}
|