@akagilnc/pi-workflow-roles 0.1.5212 → 0.1.5216

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.
@@ -2694,17 +2694,6 @@ function positiveInteger(value) {
2694
2694
  }
2695
2695
  return void 0;
2696
2696
  }
2697
- function nonNegativeInteger(value) {
2698
- if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0) return value;
2699
- if (typeof value === "string" && /^(0|[1-9][0-9]*)$/.test(value)) {
2700
- const parsed = Number(value);
2701
- if (Number.isSafeInteger(parsed)) return parsed;
2702
- }
2703
- return void 0;
2704
- }
2705
- function projectSpeaker(value) {
2706
- return value === "owner" || value === "runner" ? value : void 0;
2707
- }
2708
2697
  function projectBound(value) {
2709
2698
  if (!isRecord2(value)) return void 0;
2710
2699
  const id = typeof value.id === "string" && value.id !== "" ? value.id : void 0;
@@ -2733,42 +2722,6 @@ function projectTicketProvenanceSessions(value) {
2733
2722
  }
2734
2723
  return sessions;
2735
2724
  }
2736
- function projectTicketProvenanceHeader(value) {
2737
- if (!isRecord2(value)) return void 0;
2738
- const ticket = value.ticket === null ? null : positiveInteger(value.ticket);
2739
- if (ticket === void 0) return void 0;
2740
- if (typeof value.repo !== "string") return void 0;
2741
- if (typeof value.createdAt !== "string" || typeof value.updatedAt !== "string") {
2742
- return void 0;
2743
- }
2744
- const sessions = projectTicketProvenanceSessions(value.sessions);
2745
- if (sessions === void 0) return void 0;
2746
- return {
2747
- repo: value.repo,
2748
- ticket,
2749
- createdAt: value.createdAt,
2750
- updatedAt: value.updatedAt,
2751
- sessions
2752
- };
2753
- }
2754
- function projectTicketProvenanceLine(value) {
2755
- if (!isRecord2(value)) return void 0;
2756
- const speaker = projectSpeaker(value.speaker);
2757
- const s = nonNegativeInteger(value.s);
2758
- if (speaker === void 0 || s === void 0) return void 0;
2759
- if (typeof value.text !== "string") return void 0;
2760
- const sourcePosition = nonNegativeInteger(value.sourcePosition);
2761
- const sourceIdentity = typeof value.sourceIdentity === "string" && value.sourceIdentity !== "" ? value.sourceIdentity : void 0;
2762
- const id = typeof value.id === "string" && value.id !== "" ? value.id : void 0;
2763
- return {
2764
- speaker,
2765
- s,
2766
- ...sourcePosition === void 0 ? {} : { sourcePosition },
2767
- ...sourceIdentity === void 0 ? {} : { sourceIdentity },
2768
- ...id === void 0 ? {} : { id },
2769
- text: value.text
2770
- };
2771
- }
2772
2725
  var TICKET_PROVENANCE_KIND;
2773
2726
  var init_ticket_provenance_contracts = __esm({
2774
2727
  "src/ticket-provenance-contracts.ts"() {
@@ -7707,7 +7660,6 @@ var init_session_dialogue = __esm({
7707
7660
  });
7708
7661
 
7709
7662
  // src/ticket-provenance.ts
7710
- import { createHash as createHash6 } from "node:crypto";
7711
7663
  import { readFile as readFile12, unlink as unlink2 } from "node:fs/promises";
7712
7664
  import { basename as basename5, dirname as dirname11, join as join16, resolve as resolve9 } from "node:path";
7713
7665
  function dialogueSessionSourceRoots(home) {
@@ -7758,175 +7710,6 @@ function resolveTicketProvenanceVolume(ticketNumber, cwd, home) {
7758
7710
  );
7759
7711
  return { recordFile: path.recordFile, volumeDir: path.sessionDir };
7760
7712
  }
7761
- function projectTicketProvenanceRaw(value) {
7762
- if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
7763
- const raw = value;
7764
- if (typeof raw.raw !== "string" || !Number.isInteger(raw.s) || raw.s < 0 || !Number.isInteger(raw.sourcePosition) || raw.sourcePosition < 0) {
7765
- return void 0;
7766
- }
7767
- const sourceIdentity = typeof raw.sourceIdentity === "string" && raw.sourceIdentity !== "" ? raw.sourceIdentity : void 0;
7768
- return {
7769
- raw: raw.raw,
7770
- s: raw.s,
7771
- sourcePosition: raw.sourcePosition,
7772
- ...sourceIdentity === void 0 ? {} : { sourceIdentity }
7773
- };
7774
- }
7775
- function projectTicketProvenanceCommit(value) {
7776
- if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
7777
- const record4 = value;
7778
- if (record4.kind !== TICKET_PROVENANCE_KIND || typeof record4.timestamp !== "string") {
7779
- return void 0;
7780
- }
7781
- const payload = record4.payload;
7782
- if (typeof payload !== "object" || payload === null || Array.isArray(payload)) return void 0;
7783
- const body = payload;
7784
- if (body.type !== "ticket-provenance-append") return void 0;
7785
- const sessions = projectTicketProvenanceSessions(body.sessions);
7786
- if (sessions === void 0 || !Array.isArray(body.lines)) return void 0;
7787
- const lines = [];
7788
- for (const raw of body.lines) {
7789
- if (typeof raw === "string") {
7790
- lines.push(raw);
7791
- continue;
7792
- }
7793
- const line2 = projectTicketProvenanceLine(raw);
7794
- if (line2 !== void 0) {
7795
- lines.push(line2);
7796
- continue;
7797
- }
7798
- const preserved = projectTicketProvenanceRaw(raw);
7799
- if (preserved === void 0) return void 0;
7800
- lines.push(preserved);
7801
- }
7802
- return { timestamp: record4.timestamp, sessions, lines };
7803
- }
7804
- async function readTicketProvenance(ticketNumber, cwd, home, runDirectory) {
7805
- const { recordFile } = ticketNumber === null ? resolveSitianRecordPath(ticketProvenanceRecordInput(null, cwd, home, runDirectory)) : resolveTicketProvenanceVolume(ticketNumber, cwd, home);
7806
- let text;
7807
- try {
7808
- text = await readFile12(recordFile, "utf8");
7809
- } catch (error) {
7810
- if (error.code === "ENOENT") {
7811
- return {
7812
- header: void 0,
7813
- lines: [],
7814
- unprojectedRaw: [],
7815
- recordFile,
7816
- sourceIdentities: /* @__PURE__ */ new Map(),
7817
- legacySourcePositions: /* @__PURE__ */ new Map()
7818
- };
7819
- }
7820
- throw error;
7821
- }
7822
- const physical = text.split("\n");
7823
- let header;
7824
- const lines = [];
7825
- const unprojectedRaw = [];
7826
- const sourceIdentities = /* @__PURE__ */ new Map();
7827
- const legacySourcePositions = /* @__PURE__ */ new Map();
7828
- const rememberIdentity = (s, identity) => {
7829
- const seen = sourceIdentities.get(s) ?? /* @__PURE__ */ new Set();
7830
- const fresh = !seen.has(identity);
7831
- seen.add(identity);
7832
- sourceIdentities.set(s, seen);
7833
- return fresh;
7834
- };
7835
- const rememberLegacyPosition = (s, position) => {
7836
- const seen = legacySourcePositions.get(s) ?? /* @__PURE__ */ new Set();
7837
- seen.add(position);
7838
- legacySourcePositions.set(s, seen);
7839
- };
7840
- const remapCoverage = (coverage, priorIndexes) => {
7841
- const normalized = /* @__PURE__ */ new Map();
7842
- for (const [s, values] of coverage) {
7843
- const target = priorIndexes[s] ?? s;
7844
- const union = normalized.get(target) ?? /* @__PURE__ */ new Set();
7845
- for (const value of values) union.add(value);
7846
- normalized.set(target, union);
7847
- }
7848
- coverage.clear();
7849
- for (const [s, values] of normalized) coverage.set(s, values);
7850
- };
7851
- let sawFirst = false;
7852
- for (let index = 0; index < physical.length; index += 1) {
7853
- const raw = physical[index];
7854
- if (!raw.trim()) continue;
7855
- let parsed;
7856
- try {
7857
- parsed = JSON.parse(raw);
7858
- } catch {
7859
- unprojectedRaw.push(raw);
7860
- continue;
7861
- }
7862
- if (!sawFirst) {
7863
- sawFirst = true;
7864
- header = projectTicketProvenanceHeader(parsed);
7865
- if (header !== void 0) continue;
7866
- }
7867
- const line2 = projectTicketProvenanceLine(parsed);
7868
- if (line2 !== void 0) {
7869
- lines.push(line2);
7870
- continue;
7871
- }
7872
- const commit = projectTicketProvenanceCommit(parsed);
7873
- if (commit !== void 0) {
7874
- const merged = mergeSessionBounds(header?.sessions, commit.sessions);
7875
- remapCoverage(sourceIdentities, merged.priorIndexes);
7876
- remapCoverage(legacySourcePositions, merged.priorIndexes);
7877
- const remapped = [];
7878
- for (const entry of commit.lines) {
7879
- if (typeof entry === "string") {
7880
- unprojectedRaw.push(entry);
7881
- continue;
7882
- }
7883
- const s = merged.incomingIndexes[entry.s] ?? merged.priorIndexes[entry.s] ?? entry.s;
7884
- if ("raw" in entry) {
7885
- if (entry.sourceIdentity !== void 0) {
7886
- if (rememberIdentity(s, entry.sourceIdentity)) unprojectedRaw.push(entry.raw);
7887
- } else {
7888
- rememberLegacyPosition(s, entry.sourcePosition);
7889
- unprojectedRaw.push(entry.raw);
7890
- }
7891
- continue;
7892
- }
7893
- remapped.push({ ...entry, s });
7894
- if (entry.id === void 0) {
7895
- if (entry.sourceIdentity !== void 0) rememberIdentity(s, entry.sourceIdentity);
7896
- else if (entry.sourcePosition !== void 0) rememberLegacyPosition(s, entry.sourcePosition);
7897
- }
7898
- }
7899
- const now = commit.timestamp;
7900
- header = {
7901
- repo: header?.repo ?? resolveBookKeyFromGit(cwd),
7902
- ticket: ticketNumber,
7903
- createdAt: header?.createdAt ?? now,
7904
- updatedAt: header?.updatedAt !== void 0 && header.updatedAt > now ? header.updatedAt : now,
7905
- sessions: merged.sessions
7906
- };
7907
- const carried = lines.map((entry) => ({
7908
- ...entry,
7909
- s: merged.priorIndexes[entry.s] ?? entry.s
7910
- }));
7911
- lines.splice(0, lines.length, ...mergeFreshIntoCarried(carried, remapped));
7912
- continue;
7913
- }
7914
- unprojectedRaw.push(raw);
7915
- }
7916
- for (const line2 of lines) {
7917
- if (line2.id !== void 0) continue;
7918
- if (line2.sourceIdentity !== void 0) rememberIdentity(line2.s, line2.sourceIdentity);
7919
- else if (line2.sourcePosition !== void 0) rememberLegacyPosition(line2.s, line2.sourcePosition);
7920
- }
7921
- return {
7922
- header,
7923
- lines,
7924
- unprojectedRaw,
7925
- recordFile,
7926
- sourceIdentities,
7927
- legacySourcePositions
7928
- };
7929
- }
7930
7713
  async function rehomeUnboundTicketProvenance(runDirectory, ticketNumber, cwd, home) {
7931
7714
  const source = join16(runDirectory, "records.jsonl");
7932
7715
  let content;
@@ -7956,110 +7739,6 @@ function resolveBoundIndex(bound, sessionLines) {
7956
7739
  }
7957
7740
  return void 0;
7958
7741
  }
7959
- function dialogueIdentity(s, id) {
7960
- return `${s}\0${id}`;
7961
- }
7962
- function rangeDeclarationKey(range) {
7963
- return JSON.stringify({
7964
- from: range.from,
7965
- to: range.to
7966
- });
7967
- }
7968
- function mergeSessionBounds(prior, incoming) {
7969
- const merged = [];
7970
- const indexByIdentity = /* @__PURE__ */ new Map();
7971
- const absorb = (sessions) => {
7972
- const indexes = [];
7973
- for (const session of sessions) {
7974
- const identity = physicalPathIdentity(session.path);
7975
- let targetIndex = indexByIdentity.get(identity);
7976
- if (targetIndex === void 0) {
7977
- targetIndex = merged.length;
7978
- indexByIdentity.set(identity, targetIndex);
7979
- merged.push({ path: session.path, ranges: [] });
7980
- }
7981
- indexes.push(targetIndex);
7982
- const target = merged[targetIndex];
7983
- const seen = new Set(target.ranges.map(rangeDeclarationKey));
7984
- for (const range of session.ranges) {
7985
- const key = rangeDeclarationKey(range);
7986
- if (seen.has(key)) continue;
7987
- seen.add(key);
7988
- target.ranges.push({ from: { ...range.from }, to: { ...range.to } });
7989
- }
7990
- }
7991
- return indexes;
7992
- };
7993
- const priorIndexes = absorb(prior ?? []);
7994
- const incomingIndexes = absorb(incoming);
7995
- return { sessions: merged, priorIndexes, incomingIndexes };
7996
- }
7997
- function undeclaredSessionRanges(prior, merged) {
7998
- const priorKeys = /* @__PURE__ */ new Map();
7999
- for (const session of prior ?? []) {
8000
- const identity = physicalPathIdentity(session.path);
8001
- let keys = priorKeys.get(identity);
8002
- if (keys === void 0) {
8003
- keys = /* @__PURE__ */ new Set();
8004
- priorKeys.set(identity, keys);
8005
- }
8006
- for (const range of session.ranges) keys.add(rangeDeclarationKey(range));
8007
- }
8008
- const out = [];
8009
- for (let s = 0; s < merged.length; s += 1) {
8010
- const session = merged[s];
8011
- const identity = physicalPathIdentity(session.path);
8012
- const declared = priorKeys.get(identity) ?? /* @__PURE__ */ new Set();
8013
- const fresh = session.ranges.filter(
8014
- (range) => !declared.has(rangeDeclarationKey(range))
8015
- );
8016
- if (fresh.length === 0) continue;
8017
- out.push({
8018
- s,
8019
- session: {
8020
- path: session.path,
8021
- ranges: fresh.map((range) => ({
8022
- from: { ...range.from },
8023
- to: { ...range.to }
8024
- }))
8025
- }
8026
- });
8027
- }
8028
- return out;
8029
- }
8030
- function mergeFreshIntoCarried(carried, fresh) {
8031
- const seenSources = /* @__PURE__ */ new Map();
8032
- const bySession = /* @__PURE__ */ new Map();
8033
- const absorb = (lines) => {
8034
- for (const line2 of lines) {
8035
- const sourceIdentity = line2.id === void 0 ? line2.sourceIdentity : `id\0${line2.id}`;
8036
- const identity = sourceIdentity === void 0 ? void 0 : `${line2.s}\0${sourceIdentity}`;
8037
- const seen = identity === void 0 ? void 0 : seenSources.get(identity);
8038
- if (seen !== void 0) {
8039
- if (line2.sourcePosition !== void 0) {
8040
- Object.assign(seen, { sourcePosition: line2.sourcePosition });
8041
- }
8042
- continue;
8043
- }
8044
- const bucket = bySession.get(line2.s) ?? [];
8045
- bucket.push({ ...line2 });
8046
- if (identity !== void 0) seenSources.set(identity, bucket.at(-1));
8047
- bySession.set(line2.s, bucket);
8048
- }
8049
- };
8050
- absorb(carried);
8051
- absorb(fresh);
8052
- return [...bySession.entries()].sort(([left], [right]) => left - right).flatMap(([, lines]) => lines.map((line2, archiveIndex) => ({ line: line2, archiveIndex })).sort((left, right) => {
8053
- const leftPosition = left.line.sourcePosition;
8054
- const rightPosition = right.line.sourcePosition;
8055
- if (leftPosition === void 0 && rightPosition === void 0) {
8056
- return left.archiveIndex - right.archiveIndex;
8057
- }
8058
- if (leftPosition === void 0) return 1;
8059
- if (rightPosition === void 0) return -1;
8060
- return leftPosition - rightPosition || left.archiveIndex - right.archiveIndex;
8061
- }).map(({ line: line2 }) => line2));
8062
- }
8063
7742
  function stableSourceFacts(sessionLines) {
8064
7743
  const positionByIdentity = /* @__PURE__ */ new Map();
8065
7744
  const facts = [];
@@ -8134,13 +7813,7 @@ async function projectSessionRanges(input) {
8134
7813
  const rows = sessionLines.map((entry) => entry.row);
8135
7814
  const dialogue = adaptSessionDialogue(rows);
8136
7815
  const sourceFacts = stableSourceFacts(sessionLines);
8137
- const sourcePositionByIdentity = /* @__PURE__ */ new Map();
8138
- for (const fact of sourceFacts) {
8139
- sourcePositionByIdentity.set(fact.identity, fact.position);
8140
- }
8141
- const seenIds = input.seenIds;
8142
- const lines = [];
8143
- const raw = [];
7816
+ const entries = [];
8144
7817
  const ranges = normalizeResolvedRanges(
8145
7818
  input.session.ranges,
8146
7819
  sessionLines,
@@ -8149,19 +7822,13 @@ async function projectSessionRanges(input) {
8149
7822
  for (const range of ranges) {
8150
7823
  for (let index = range.fromIndex; index <= range.toIndex; index += 1) {
8151
7824
  const { position: sourcePosition, identity: sourceIdentity } = sourceFacts[index];
8152
- if (input.coveredSourceIdentities.has(sourceIdentity) || input.legacyCoveredSourcePositions.has(sourcePosition)) continue;
8153
7825
  const entry = sessionLines[index];
8154
7826
  if (entry.row === void 0) {
8155
- raw.push({ raw: entry.raw, s: input.s, sourcePosition, sourceIdentity });
7827
+ entries.push({ raw: entry.raw, s: input.s, sourcePosition, sourceIdentity });
8156
7828
  continue;
8157
7829
  }
8158
7830
  for (const event of dialogue[index] ?? []) {
8159
- if (event.id !== void 0) {
8160
- const identity = dialogueIdentity(input.s, event.id);
8161
- if (seenIds.has(identity)) continue;
8162
- seenIds.add(identity);
8163
- }
8164
- lines.push({
7831
+ entries.push({
8165
7832
  speaker: event.speaker,
8166
7833
  s: input.s,
8167
7834
  sourcePosition,
@@ -8171,106 +7838,49 @@ async function projectSessionRanges(input) {
8171
7838
  }
8172
7839
  }
8173
7840
  }
8174
- return { lines, raw, sourcePositionByIdentity };
7841
+ return { entries };
8175
7842
  }
8176
7843
  async function reprojectTicketProvenance(input) {
8177
- const prior = await readTicketProvenance(input.ticketNumber, input.cwd, input.home, input.runDirectory);
7844
+ const recordInput = ticketProvenanceRecordInput(
7845
+ input.ticketNumber,
7846
+ input.cwd,
7847
+ input.home,
7848
+ input.runDirectory
7849
+ );
7850
+ const resolved = resolveSitianRecordPath(recordInput);
8178
7851
  if (input.sessions.length === 0) {
8179
- const now2 = (/* @__PURE__ */ new Date()).toISOString();
8180
7852
  return {
8181
- recordFile: prior.recordFile,
8182
- header: prior.header ?? {
8183
- repo: resolveBookKeyFromGit(input.cwd),
8184
- ticket: input.ticketNumber,
8185
- createdAt: now2,
8186
- updatedAt: now2,
8187
- sessions: []
8188
- },
8189
- lines: prior.lines
8190
- };
8191
- }
8192
- const merged = mergeSessionBounds(prior.header?.sessions, input.sessions);
8193
- const deltas = undeclaredSessionRanges(prior.header?.sessions, merged.sessions);
8194
- if (deltas.length === 0) {
8195
- const now2 = (/* @__PURE__ */ new Date()).toISOString();
8196
- return {
8197
- recordFile: prior.recordFile,
8198
- header: prior.header ?? {
8199
- repo: resolveBookKeyFromGit(input.cwd),
8200
- ticket: input.ticketNumber,
8201
- createdAt: now2,
8202
- updatedAt: now2,
8203
- sessions: merged.sessions
8204
- },
8205
- lines: prior.lines
7853
+ recordFile: resolved.recordFile,
7854
+ lines: []
8206
7855
  };
8207
7856
  }
8208
- const seenIds = new Set(
8209
- prior.lines.flatMap(
8210
- (line2) => line2.id === void 0 ? [] : [dialogueIdentity(line2.s, line2.id)]
8211
- )
8212
- );
8213
- const fresh = [];
8214
- const raw = [];
8215
- for (const delta of deltas) {
7857
+ const entries = [];
7858
+ for (let s = 0; s < input.sessions.length; s += 1) {
7859
+ const session = input.sessions[s];
8216
7860
  const projected = await projectSessionRanges({
8217
- s: delta.s,
8218
- session: delta.session,
8219
- seenIds,
8220
- coveredSourceIdentities: prior.sourceIdentities.get(delta.s) ?? /* @__PURE__ */ new Set(),
8221
- legacyCoveredSourcePositions: prior.legacySourcePositions.get(delta.s) ?? /* @__PURE__ */ new Set(),
7861
+ s,
7862
+ session,
8222
7863
  ...input.home === void 0 ? {} : { home: input.home }
8223
7864
  });
8224
- fresh.push(...prior.lines.flatMap((line2) => {
8225
- if (line2.s !== delta.s) return [];
8226
- const sourceIdentity = line2.id === void 0 ? line2.sourceIdentity : `id\0${line2.id}`;
8227
- if (sourceIdentity === void 0) return [];
8228
- const sourcePosition = projected.sourcePositionByIdentity.get(sourceIdentity);
8229
- return sourcePosition === void 0 ? [] : [{ ...line2, sourcePosition }];
8230
- }));
8231
- fresh.push(...projected.lines);
8232
- raw.push(...projected.raw);
8233
- }
8234
- const lines = mergeFreshIntoCarried(prior.lines, fresh);
8235
- const now = (/* @__PURE__ */ new Date()).toISOString();
8236
- const header = {
8237
- repo: prior.header?.repo ?? resolveBookKeyFromGit(input.cwd),
8238
- ticket: input.ticketNumber,
8239
- createdAt: prior.header?.createdAt ?? now,
8240
- updatedAt: now,
8241
- sessions: merged.sessions
8242
- };
8243
- const identityMaterial = JSON.stringify({
8244
- ticket: input.ticketNumber,
8245
- deltas: deltas.map(({ s, session }) => ({
8246
- s,
8247
- path: physicalPathIdentity(session.path),
8248
- ranges: session.ranges
8249
- })),
8250
- lines: [...fresh, ...raw]
8251
- });
8252
- const identity = `ticket-provenance:${createHash6("sha256").update(identityMaterial).digest("hex")}`;
7865
+ entries.push(...projected.entries);
7866
+ }
8253
7867
  const pointer = appendSitianRecord({
8254
- ...ticketProvenanceRecordInput(input.ticketNumber, input.cwd, input.home, input.runDirectory),
8255
- identity,
7868
+ ...recordInput,
8256
7869
  payload: {
8257
7870
  type: "ticket-provenance-append",
8258
- sessions: merged.sessions,
8259
- lines: [...fresh, ...raw]
7871
+ sessions: input.sessions,
7872
+ lines: entries
8260
7873
  }
8261
7874
  });
8262
- const folded = await readTicketProvenance(input.ticketNumber, input.cwd, input.home, input.runDirectory);
8263
7875
  return {
8264
7876
  recordFile: pointer.recordFile,
8265
- header: folded.header ?? header,
8266
- lines: folded.lines
7877
+ lines: entries.filter((entry) => "speaker" in entry)
8267
7878
  };
8268
7879
  }
8269
7880
  var TicketProvenanceInputError;
8270
7881
  var init_ticket_provenance = __esm({
8271
7882
  "src/ticket-provenance.ts"() {
8272
7883
  "use strict";
8273
- init_activation_ledger_git();
8274
7884
  init_activation_ledger_topology();
8275
7885
  init_ledger_session_read();
8276
7886
  init_run_ticket_number();
@@ -19901,7 +19511,7 @@ var init_analyst_metric_family = __esm({
19901
19511
  });
19902
19512
 
19903
19513
  // src/analyst-page.ts
19904
- import { createHash as createHash7 } from "node:crypto";
19514
+ import { createHash as createHash6 } from "node:crypto";
19905
19515
  import { dirname as dirname22, join as join37 } from "node:path";
19906
19516
  function analystIssuePageKey(address) {
19907
19517
  const parts = ["book", address.bookKey];
@@ -19910,7 +19520,7 @@ function analystIssuePageKey(address) {
19910
19520
  } else if (address.scopeRootIdentity !== void 0) {
19911
19521
  parts.push("root", physicalPathIdentity(address.scopeRootIdentity));
19912
19522
  }
19913
- return createHash7("sha256").update(parts.join("\0")).digest("hex").slice(0, 32);
19523
+ return createHash6("sha256").update(parts.join("\0")).digest("hex").slice(0, 32);
19914
19524
  }
19915
19525
  function analystIssuePagePath(ledgerHome, address) {
19916
19526
  return join37(ledgerHome, "analyst", "issues", `${analystIssuePageKey(address)}.json`);
@@ -23348,7 +22958,7 @@ var init_run_lifecycle = __esm({
23348
22958
  });
23349
22959
 
23350
22960
  // src/archivist-record-topology.ts
23351
- import { createHash as createHash8 } from "node:crypto";
22961
+ import { createHash as createHash7 } from "node:crypto";
23352
22962
  import { join as join42 } from "node:path";
23353
22963
  function resolveNavigatorWorkSubjectPlacement(input) {
23354
22964
  let ledgerHome;
@@ -23359,7 +22969,7 @@ function resolveNavigatorWorkSubjectPlacement(input) {
23359
22969
  }
23360
22970
  }
23361
22971
  ledgerHome ??= resolveActivationLedgerHome(input.home);
23362
- const digest = createHash8("sha256").update(input.subject).digest("hex").slice(0, 32);
22972
+ const digest = createHash7("sha256").update(input.subject).digest("hex").slice(0, 32);
23363
22973
  return {
23364
22974
  ledgerHome,
23365
22975
  sessionDir: join42(
@@ -23739,7 +23349,7 @@ import { readFile as readFile26 } from "node:fs/promises";
23739
23349
  import { join as join47 } from "node:path";
23740
23350
 
23741
23351
  // src/navigator-attendance.ts
23742
- import { createHash as createHash9 } from "node:crypto";
23352
+ import { createHash as createHash8 } from "node:crypto";
23743
23353
  init_navigator_invocation_identity();
23744
23354
  init_packaged_role_registry();
23745
23355
  init_activation_ledger_topology();
@@ -24300,7 +23910,7 @@ function navigatorSubjectKey(subjectRoot, subject, provenance = "role_input") {
24300
23910
  if (provenance === "placeholder") return subjectRoot;
24301
23911
  const normalized = subject.trim().replace(/\s+/g, " ");
24302
23912
  if (normalized === "") return subjectRoot;
24303
- return `${subjectRoot}#${createHash9("sha256").update(normalized).digest("hex").slice(0, 32)}`;
23913
+ return `${subjectRoot}#${createHash8("sha256").update(normalized).digest("hex").slice(0, 32)}`;
24304
23914
  }
24305
23915
  function navigatorSubjectKeyForInput(subjectRoot, reference, cwd = process.cwd()) {
24306
23916
  if (issueRoot(subjectRoot) !== void 0 || !subjectRoot.includes("/.ak/work/")) return subjectRoot;
@@ -15038,7 +15038,6 @@ var init_sitian_facade = __esm({
15038
15038
  var init_ticket_provenance = __esm({
15039
15039
  "src/ticket-provenance.ts"() {
15040
15040
  "use strict";
15041
- init_activation_ledger_git();
15042
15041
  init_activation_ledger_topology();
15043
15042
  init_ledger_session_read();
15044
15043
  init_run_ticket_number();
@@ -19272,7 +19272,6 @@ async function rehomeUnboundTicketProvenance(runDirectory, ticketNumber, cwd, ho
19272
19272
  var init_ticket_provenance = __esm({
19273
19273
  "src/ticket-provenance.ts"() {
19274
19274
  "use strict";
19275
- init_activation_ledger_git();
19276
19275
  init_activation_ledger_topology();
19277
19276
  init_ledger_session_read();
19278
19277
  init_run_ticket_number();
@@ -1,10 +1,9 @@
1
1
  /**
2
- * 起居录(ticket-provenance)typed 形状 —— ADR 0075「2026-09-14 修订」/ #901 / #918。
2
+ * 起居录(ticket-provenance)typed 形状 —— ADR 0075 / ADR 0081 / #1090。
3
3
  *
4
- * 一册=一个追加式 records.jsonl;逻辑册子头与对话由读取时折叠不可变投影提交得到。
5
- * 既有「首行册子头+裸对话行」snapshot 向后可读,后续提交不回写旧行。
6
- * sessions 为 prior ∪ 各轮累计并集(遗漏不删除),已结转正文不因历史源重读而改。
7
- * 交卷 `sessions` 输入语义仍是「本轮对话边界」;累计并集是机械合并,不是角色交什么。
4
+ * 一册=一个追加式 records.jsonl。每轮交卷的 `sessions`=本轮对话边界;
5
+ * 成录接缝按该边界从宿主卷投影并追加,不回读已成录历史去重或折叠。
6
+ * 既有「首行册子头+裸对话行」snapshot 仍可读;后续提交不回写旧行。
8
7
  */
9
8
  /** Sitian kind for per-ticket court diary volumes. */
10
9
  export const TICKET_PROVENANCE_KIND = "ticket-provenance";
@@ -21,19 +20,6 @@ function positiveInteger(value) {
21
20
  }
22
21
  return undefined;
23
22
  }
24
- function nonNegativeInteger(value) {
25
- if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0)
26
- return value;
27
- if (typeof value === "string" && /^(0|[1-9][0-9]*)$/.test(value)) {
28
- const parsed = Number(value);
29
- if (Number.isSafeInteger(parsed))
30
- return parsed;
31
- }
32
- return undefined;
33
- }
34
- function projectSpeaker(value) {
35
- return value === "owner" || value === "runner" ? value : undefined;
36
- }
37
23
  function projectBound(value) {
38
24
  if (!isRecord(value))
39
25
  return undefined;
@@ -102,27 +88,3 @@ export function projectTicketProvenanceHeader(value) {
102
88
  sessions,
103
89
  };
104
90
  }
105
- /** 读回一条对话行。 */
106
- export function projectTicketProvenanceLine(value) {
107
- if (!isRecord(value))
108
- return undefined;
109
- const speaker = projectSpeaker(value.speaker);
110
- const s = nonNegativeInteger(value.s);
111
- if (speaker === undefined || s === undefined)
112
- return undefined;
113
- if (typeof value.text !== "string")
114
- return undefined;
115
- const sourcePosition = nonNegativeInteger(value.sourcePosition);
116
- const sourceIdentity = typeof value.sourceIdentity === "string" && value.sourceIdentity !== ""
117
- ? value.sourceIdentity
118
- : undefined;
119
- const id = typeof value.id === "string" && value.id !== "" ? value.id : undefined;
120
- return {
121
- speaker,
122
- s,
123
- ...(sourcePosition === undefined ? {} : { sourcePosition }),
124
- ...(sourceIdentity === undefined ? {} : { sourceIdentity }),
125
- ...(id === undefined ? {} : { id }),
126
- text: value.text,
127
- };
128
- }