@akagilnc/pi-workflow-roles 0.1.4422 → 0.1.4489

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.
Files changed (53) hide show
  1. package/README.md +2 -0
  2. package/README.zh-CN.md +2 -0
  3. package/dist/acp-host/description.js +2 -3
  4. package/dist/acp-host/production-host.js +333 -258
  5. package/dist/auditor-soul.js +8 -1
  6. package/dist/diarist-contracts.js +2 -11
  7. package/dist/headless-host/description.js +3 -3
  8. package/dist/headless-host/production-host.js +340 -227
  9. package/dist/host-descriptions.js +3 -18
  10. package/dist/method-host-plugin/.claude-plugin/plugin.json +5 -0
  11. package/dist/method-host-plugin/skills/ak-cross-m-review/CONTEXT.md +48 -0
  12. package/dist/method-host-plugin/skills/ak-cross-m-review/LICENSE +21 -0
  13. package/dist/method-host-plugin/skills/ak-cross-m-review/SKILL.md +170 -0
  14. package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-completeness.md +118 -0
  15. package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-reviewer.md +128 -0
  16. package/dist/method-host-plugin/skills/ak-cross-m-review/provenance.json +41 -0
  17. package/dist/method-host-plugin/skills/diagnosing-bugs/SKILL.md +134 -0
  18. package/dist/method-host-plugin/skills/diagnosing-bugs/agents/openai.yaml +3 -0
  19. package/dist/method-host-plugin/skills/diagnosing-bugs/provenance.json +31 -0
  20. package/dist/method-host-plugin/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
  21. package/dist/method-host-plugin/skills/resolving-merge-conflicts/SKILL.md +14 -0
  22. package/dist/method-host-plugin/skills/resolving-merge-conflicts/agents/openai.yaml +3 -0
  23. package/dist/method-host-plugin/skills/resolving-merge-conflicts/provenance.json +26 -0
  24. package/dist/method-host-plugin/skills/tdd/SKILL.md +38 -0
  25. package/dist/method-host-plugin/skills/tdd/agents/openai.yaml +3 -0
  26. package/dist/method-host-plugin/skills/tdd/mocking.md +59 -0
  27. package/dist/method-host-plugin/skills/tdd/provenance.json +36 -0
  28. package/dist/method-host-plugin/skills/tdd/tests.md +77 -0
  29. package/dist/public-cli/main.js +14 -21
  30. package/dist/session-opening-materials.js +17 -5
  31. package/dist/ticket-provenance-contracts.js +6 -25
  32. package/dist/ticket-provenance.js +223 -90
  33. package/extensions/role-runtime.ts +16 -6
  34. package/package.json +1 -1
  35. package/resources/method-host-plugin/.claude-plugin/plugin.json +5 -0
  36. package/scripts/build-package.mjs +6 -1
  37. package/src/acp-host/description.ts +2 -4
  38. package/src/acp-host/production-host.ts +0 -1
  39. package/src/auditor-soul.ts +10 -1
  40. package/src/diarist-contracts.ts +1 -19
  41. package/src/diarist-role.ts +3 -31
  42. package/src/diarist.ts +5 -19
  43. package/src/headless-host/description.ts +4 -3
  44. package/src/headless-host/role-turn-host.ts +27 -4
  45. package/src/host-descriptions.ts +3 -23
  46. package/src/host-native-method.ts +67 -0
  47. package/src/ledger-session-read.ts +1 -2
  48. package/src/role-envelope.ts +17 -47
  49. package/src/role-runtime-dependencies.ts +17 -2
  50. package/src/role-runtime.ts +14 -31
  51. package/src/session-opening-materials.ts +27 -11
  52. package/src/ticket-provenance-contracts.ts +11 -38
  53. package/src/ticket-provenance.ts +228 -109
@@ -1521,10 +1521,10 @@ __export(session_assistant_usage_exports, {
1521
1521
  });
1522
1522
  import { join as join8 } from "node:path";
1523
1523
  async function readAssistantUsageFromSessionFile(sessionFile) {
1524
- const { readFile: readFile24 } = await import("node:fs/promises");
1524
+ const { readFile: readFile23 } = await import("node:fs/promises");
1525
1525
  let text;
1526
1526
  try {
1527
- text = await readFile24(sessionFile, "utf8");
1527
+ text = await readFile23(sessionFile, "utf8");
1528
1528
  } catch (error) {
1529
1529
  if (error?.code === "ENOENT") return void 0;
1530
1530
  throw error;
@@ -2366,21 +2366,6 @@ function projectTicketProvenanceSessions(value) {
2366
2366
  }
2367
2367
  return sessions;
2368
2368
  }
2369
- function projectTicketProvenanceAmendments(value) {
2370
- if (!Array.isArray(value)) return [];
2371
- const out = [];
2372
- for (const raw of value) {
2373
- if (!isRecord(raw)) continue;
2374
- const s = nonNegativeInteger(raw.s);
2375
- const line2 = positiveInteger(raw.line);
2376
- const speaker = projectSpeaker(raw.speaker);
2377
- const text = raw.text;
2378
- if (s === void 0 || line2 === void 0 || speaker === void 0) continue;
2379
- if (typeof text !== "string") continue;
2380
- out.push({ s, line: line2, speaker, text });
2381
- }
2382
- return out;
2383
- }
2384
2369
  function projectTicketProvenanceHeader(value) {
2385
2370
  if (!isRecord(value)) return void 0;
2386
2371
  const ticket = positiveInteger(value.ticket);
@@ -2405,12 +2390,14 @@ function projectTicketProvenanceLine(value) {
2405
2390
  const s = nonNegativeInteger(value.s);
2406
2391
  if (speaker === void 0 || s === void 0) return void 0;
2407
2392
  if (typeof value.text !== "string") return void 0;
2408
- const line2 = positiveInteger(value.line);
2393
+ const sourcePosition = nonNegativeInteger(value.sourcePosition);
2394
+ const sourceIdentity = typeof value.sourceIdentity === "string" && value.sourceIdentity !== "" ? value.sourceIdentity : void 0;
2409
2395
  const id = typeof value.id === "string" && value.id !== "" ? value.id : void 0;
2410
2396
  return {
2411
2397
  speaker,
2412
2398
  s,
2413
- ...line2 === void 0 ? {} : { line: line2 },
2399
+ ...sourcePosition === void 0 ? {} : { sourcePosition },
2400
+ ...sourceIdentity === void 0 ? {} : { sourceIdentity },
2414
2401
  ...id === void 0 ? {} : { id },
2415
2402
  text: value.text
2416
2403
  };
@@ -2502,11 +2489,6 @@ function projectDiaristSessions(value) {
2502
2489
  if (raw === void 0) return [];
2503
2490
  return projectTicketProvenanceSessions(raw);
2504
2491
  }
2505
- function projectDiaristAmendments(value) {
2506
- const raw = value?.amendments;
2507
- if (raw === void 0) return [];
2508
- return projectTicketProvenanceAmendments(raw);
2509
- }
2510
2492
  var DIARIST_OUTPUT_TOOL_NAME, DIARIST_ACCEPTED_TEXT;
2511
2493
  var init_diarist_contracts = __esm({
2512
2494
  "src/diarist-contracts.ts"() {
@@ -3516,13 +3498,10 @@ function assertRegisteredHostName(host) {
3516
3498
  }
3517
3499
  throw new Error(`unregistered host: ${host}`);
3518
3500
  }
3519
- var PRIVATE_COMPAT_ENV, DEFAULT_ROLE_TURN_HOST, HOST_DESCRIPTIONS, HEADLESS_HOST_DESCRIPTIONS;
3501
+ var DEFAULT_ROLE_TURN_HOST, HOST_DESCRIPTIONS, HEADLESS_HOST_DESCRIPTIONS;
3520
3502
  var init_host_descriptions = __esm({
3521
3503
  "src/host-descriptions.ts"() {
3522
3504
  "use strict";
3523
- PRIVATE_COMPAT_ENV = Object.fromEntries(
3524
- ["CLAUDE", "CURSOR", "CODEX"].flatMap((vendor) => ["SKILLS", "RULES", "AGENTS", "MCPS", "HOOKS", "SESSIONS"].map((kind) => [`GROK_${vendor}_${kind}_ENABLED`, "false"]))
3525
- );
3526
3505
  DEFAULT_ROLE_TURN_HOST = "pi";
3527
3506
  HOST_DESCRIPTIONS = Object.freeze({
3528
3507
  /** Operator home `~/.grok`, native session/load resume, `agent [--model X] stdio`. */
@@ -3535,12 +3514,7 @@ var init_host_descriptions = __esm({
3535
3514
  }),
3536
3515
  modelPassing: "argv",
3537
3516
  boundResume: "session/load",
3538
- sessionBindingFile: "grok-acp-session.json",
3539
- childEnv: Object.freeze({
3540
- ...PRIVATE_COMPAT_ENV,
3541
- GROK_MEMORY: "0",
3542
- GROK_SUBAGENTS: "0"
3543
- })
3517
+ sessionBindingFile: "grok-acp-session.json"
3544
3518
  }),
3545
3519
  /**
3546
3520
  * Operator home `~/.hermes`, native session/load resume, `acp` subcommand.
@@ -3559,7 +3533,6 @@ var init_host_descriptions = __esm({
3559
3533
  modelPassing: "set_model",
3560
3534
  boundResume: "session/load",
3561
3535
  sessionBindingFile: "hermes-acp-session.json",
3562
- childEnv: Object.freeze({}),
3563
3536
  seatProfileSoul: Object.freeze({
3564
3537
  flag: "-p",
3565
3538
  namePrefix: "ak-",
@@ -3580,12 +3553,7 @@ var init_host_descriptions = __esm({
3580
3553
  // Intermediate assistant/tool/system events require verbose with stream-json.
3581
3554
  "--verbose",
3582
3555
  "--permission-mode",
3583
- "bypassPermissions",
3584
- // Empty sources: no user/project/local operator surface (envelope owns materials).
3585
- "--setting-sources",
3586
- "",
3587
- // With adapter-supplied --mcp-config only (AK relay); drops operator + claude.ai MCP.
3588
- "--strict-mcp-config"
3556
+ "bypassPermissions"
3589
3557
  ]),
3590
3558
  promptFlag: "-p",
3591
3559
  modelFlag: "--model",
@@ -11291,10 +11259,10 @@ function pairGateRounds(volumes) {
11291
11259
  return rounds.sort((a, b) => a.officerStartedAt.localeCompare(b.officerStartedAt)).map((round, index) => ({ ...round, roundIndex: index + 1 }));
11292
11260
  }
11293
11261
  async function resolveOfficerSessionFromPointerFile(pointerPath) {
11294
- const { readFile: readFile24 } = await import("node:fs/promises");
11262
+ const { readFile: readFile23 } = await import("node:fs/promises");
11295
11263
  let raw;
11296
11264
  try {
11297
- raw = JSON.parse(await readFile24(pointerPath, "utf8"));
11265
+ raw = JSON.parse(await readFile23(pointerPath, "utf8"));
11298
11266
  } catch (error) {
11299
11267
  throw new Error(
11300
11268
  `direct officer run pointer unreadable in ${pointerPath}: ${error instanceof Error ? error.message : String(error)}`,
@@ -11895,16 +11863,27 @@ async function readPackageMaterial(relativePath) {
11895
11863
  }
11896
11864
  async function joinPackageMaterials(relativePaths) {
11897
11865
  const chunks = [];
11898
- for (const relativePath of relativePaths) {
11899
- chunks.push(await readPackageMaterial(relativePath));
11900
- }
11866
+ for (const relativePath of relativePaths) chunks.push(await readPackageMaterial(relativePath));
11901
11867
  return chunks.join("\n\n");
11902
11868
  }
11869
+ function roleSoulPath(role, materials) {
11870
+ const suffix = `/souls/${role}.md`;
11871
+ const path = materials.find((candidate) => `/${candidate}`.endsWith(suffix));
11872
+ if (path === void 0) throw new Error(`session materials omit the ${role} Soul`);
11873
+ return path;
11874
+ }
11875
+ async function loadSeparatedSessionPart(role, materials, part) {
11876
+ const soul = roleSoulPath(role, materials);
11877
+ return part === "soul" ? readPackageMaterial(soul) : joinPackageMaterials(materials.filter((path) => path !== soul));
11878
+ }
11903
11879
  function loadMainRoleSessionMaterials(role) {
11904
- return joinPackageMaterials(MAIN_ROLE_SESSION_MATERIALS[role]);
11880
+ return loadSeparatedSessionPart(role, MAIN_ROLE_SESSION_MATERIALS[role], "soul");
11881
+ }
11882
+ function loadMainRoleReferenceMaterials(role) {
11883
+ return loadSeparatedSessionPart(role, MAIN_ROLE_SESSION_MATERIALS[role], "references");
11905
11884
  }
11906
11885
  function loadGatekeeperSessionMaterials(role) {
11907
- return joinPackageMaterials(GATEKEEPER_SESSION_MATERIALS[role]);
11886
+ return loadSeparatedSessionPart(role, GATEKEEPER_SESSION_MATERIALS[role], "soul");
11908
11887
  }
11909
11888
  var packageRootUrl, MAIN_ROLE_SESSION_MATERIALS, GATEKEEPER_SESSION_MATERIALS;
11910
11889
  var init_session_opening_materials = __esm({
@@ -11934,6 +11913,8 @@ __export(auditor_soul_exports, {
11934
11913
  AUDITOR_SESSION_MATERIALS: () => AUDITOR_SESSION_MATERIALS,
11935
11914
  AUDITOR_SOUL_ROLES: () => AUDITOR_SOUL_ROLES,
11936
11915
  isAuditorSoulRole: () => isAuditorSoulRole,
11916
+ loadAuditorReferenceMaterials: () => loadAuditorReferenceMaterials,
11917
+ loadAuditorReferenceMaterialsFromSubjectInput: () => loadAuditorReferenceMaterialsFromSubjectInput,
11937
11918
  loadAuditorSoul: () => loadAuditorSoul,
11938
11919
  loadAuditorSoulFromSubjectInput: () => loadAuditorSoulFromSubjectInput,
11939
11920
  resolveAuditorSubject: () => resolveAuditorSubject
@@ -11960,11 +11941,18 @@ async function loadAuditorSoul(role) {
11960
11941
  if (soul.trim().length === 0) {
11961
11942
  throw new Error(`The ${role} auditor Soul is blank`);
11962
11943
  }
11963
- return joinPackageMaterials(materials);
11944
+ return soul;
11945
+ }
11946
+ function loadAuditorReferenceMaterials(role) {
11947
+ const soulPath = auditorSoulRelativePath(role);
11948
+ return joinPackageMaterials(AUDITOR_SESSION_MATERIALS[role].filter((path) => path !== soulPath));
11964
11949
  }
11965
11950
  async function loadAuditorSoulFromSubjectInput(raw) {
11966
11951
  return loadAuditorSoul(resolveAuditorSubject(raw));
11967
11952
  }
11953
+ function loadAuditorReferenceMaterialsFromSubjectInput(raw) {
11954
+ return loadAuditorReferenceMaterials(resolveAuditorSubject(raw));
11955
+ }
11968
11956
  var AUDITOR_SOUL_ROLES, AK_ROLE_AUDITOR_SUBJECT_ENV, AK_ROLE_AUDITOR_SOURCE_RUN_ENV, AUDITOR_SESSION_MATERIALS;
11969
11957
  var init_auditor_soul = __esm({
11970
11958
  "src/auditor-soul.ts"() {
@@ -16951,6 +16939,20 @@ function resolveTicketProvenanceVolume(ticketNumber, cwd, home) {
16951
16939
  );
16952
16940
  return { recordFile: path.recordFile, volumeDir: path.sessionDir };
16953
16941
  }
16942
+ function projectTicketProvenanceRaw(value) {
16943
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
16944
+ const raw = value;
16945
+ if (typeof raw.raw !== "string" || !Number.isInteger(raw.s) || raw.s < 0 || !Number.isInteger(raw.sourcePosition) || raw.sourcePosition < 0) {
16946
+ return void 0;
16947
+ }
16948
+ const sourceIdentity = typeof raw.sourceIdentity === "string" && raw.sourceIdentity !== "" ? raw.sourceIdentity : void 0;
16949
+ return {
16950
+ raw: raw.raw,
16951
+ s: raw.s,
16952
+ sourcePosition: raw.sourcePosition,
16953
+ ...sourceIdentity === void 0 ? {} : { sourceIdentity }
16954
+ };
16955
+ }
16954
16956
  function projectTicketProvenanceCommit(value) {
16955
16957
  if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
16956
16958
  const record4 = value;
@@ -16965,9 +16967,18 @@ function projectTicketProvenanceCommit(value) {
16965
16967
  if (sessions === void 0 || !Array.isArray(body.lines)) return void 0;
16966
16968
  const lines = [];
16967
16969
  for (const raw of body.lines) {
16970
+ if (typeof raw === "string") {
16971
+ lines.push(raw);
16972
+ continue;
16973
+ }
16968
16974
  const line2 = projectTicketProvenanceLine(raw);
16969
- if (line2 === void 0) return void 0;
16970
- lines.push(line2);
16975
+ if (line2 !== void 0) {
16976
+ lines.push(line2);
16977
+ continue;
16978
+ }
16979
+ const preserved = projectTicketProvenanceRaw(raw);
16980
+ if (preserved === void 0) return void 0;
16981
+ lines.push(preserved);
16971
16982
  }
16972
16983
  return { timestamp: record4.timestamp, sessions, lines };
16973
16984
  }
@@ -16978,7 +16989,14 @@ async function readTicketProvenance(ticketNumber, cwd, home) {
16978
16989
  text = await readFile17(recordFile, "utf8");
16979
16990
  } catch (error) {
16980
16991
  if (error.code === "ENOENT") {
16981
- return { header: void 0, lines: [], unprojectedRaw: [], recordFile };
16992
+ return {
16993
+ header: void 0,
16994
+ lines: [],
16995
+ unprojectedRaw: [],
16996
+ recordFile,
16997
+ sourceIdentities: /* @__PURE__ */ new Map(),
16998
+ legacySourcePositions: /* @__PURE__ */ new Map()
16999
+ };
16982
17000
  }
16983
17001
  throw error;
16984
17002
  }
@@ -16986,6 +17004,31 @@ async function readTicketProvenance(ticketNumber, cwd, home) {
16986
17004
  let header;
16987
17005
  const lines = [];
16988
17006
  const unprojectedRaw = [];
17007
+ const sourceIdentities = /* @__PURE__ */ new Map();
17008
+ const legacySourcePositions = /* @__PURE__ */ new Map();
17009
+ const rememberIdentity = (s, identity) => {
17010
+ const seen = sourceIdentities.get(s) ?? /* @__PURE__ */ new Set();
17011
+ const fresh = !seen.has(identity);
17012
+ seen.add(identity);
17013
+ sourceIdentities.set(s, seen);
17014
+ return fresh;
17015
+ };
17016
+ const rememberLegacyPosition = (s, position) => {
17017
+ const seen = legacySourcePositions.get(s) ?? /* @__PURE__ */ new Set();
17018
+ seen.add(position);
17019
+ legacySourcePositions.set(s, seen);
17020
+ };
17021
+ const remapCoverage = (coverage, priorIndexes) => {
17022
+ const normalized = /* @__PURE__ */ new Map();
17023
+ for (const [s, values] of coverage) {
17024
+ const target = priorIndexes[s] ?? s;
17025
+ const union = normalized.get(target) ?? /* @__PURE__ */ new Set();
17026
+ for (const value of values) union.add(value);
17027
+ normalized.set(target, union);
17028
+ }
17029
+ coverage.clear();
17030
+ for (const [s, values] of normalized) coverage.set(s, values);
17031
+ };
16989
17032
  let sawFirst = false;
16990
17033
  for (let index = 0; index < physical.length; index += 1) {
16991
17034
  const raw = physical[index];
@@ -17010,10 +17053,30 @@ async function readTicketProvenance(ticketNumber, cwd, home) {
17010
17053
  const commit = projectTicketProvenanceCommit(parsed);
17011
17054
  if (commit !== void 0) {
17012
17055
  const merged = mergeSessionBounds(header?.sessions, commit.sessions);
17013
- const remapped = commit.lines.map((entry) => ({
17014
- ...entry,
17015
- s: merged.incomingIndexes[entry.s] ?? entry.s
17016
- }));
17056
+ remapCoverage(sourceIdentities, merged.priorIndexes);
17057
+ remapCoverage(legacySourcePositions, merged.priorIndexes);
17058
+ const remapped = [];
17059
+ for (const entry of commit.lines) {
17060
+ if (typeof entry === "string") {
17061
+ unprojectedRaw.push(entry);
17062
+ continue;
17063
+ }
17064
+ const s = merged.incomingIndexes[entry.s] ?? merged.priorIndexes[entry.s] ?? entry.s;
17065
+ if ("raw" in entry) {
17066
+ if (entry.sourceIdentity !== void 0) {
17067
+ if (rememberIdentity(s, entry.sourceIdentity)) unprojectedRaw.push(entry.raw);
17068
+ } else {
17069
+ rememberLegacyPosition(s, entry.sourcePosition);
17070
+ unprojectedRaw.push(entry.raw);
17071
+ }
17072
+ continue;
17073
+ }
17074
+ remapped.push({ ...entry, s });
17075
+ if (entry.id === void 0) {
17076
+ if (entry.sourceIdentity !== void 0) rememberIdentity(s, entry.sourceIdentity);
17077
+ else if (entry.sourcePosition !== void 0) rememberLegacyPosition(s, entry.sourcePosition);
17078
+ }
17079
+ }
17017
17080
  const now = commit.timestamp;
17018
17081
  header = {
17019
17082
  repo: header?.repo ?? resolveBookKeyFromGit(cwd),
@@ -17031,7 +17094,19 @@ async function readTicketProvenance(ticketNumber, cwd, home) {
17031
17094
  }
17032
17095
  unprojectedRaw.push(raw);
17033
17096
  }
17034
- return { header, lines, unprojectedRaw, recordFile };
17097
+ for (const line2 of lines) {
17098
+ if (line2.id !== void 0) continue;
17099
+ if (line2.sourceIdentity !== void 0) rememberIdentity(line2.s, line2.sourceIdentity);
17100
+ else if (line2.sourcePosition !== void 0) rememberLegacyPosition(line2.s, line2.sourcePosition);
17101
+ }
17102
+ return {
17103
+ header,
17104
+ lines,
17105
+ unprojectedRaw,
17106
+ recordFile,
17107
+ sourceIdentities,
17108
+ legacySourcePositions
17109
+ };
17035
17110
  }
17036
17111
  function resolveBoundIndex(bound, sessionLines) {
17037
17112
  if (typeof bound.id === "string" && bound.id !== "") {
@@ -17050,8 +17125,8 @@ function resolveBoundIndex(bound, sessionLines) {
17050
17125
  }
17051
17126
  return void 0;
17052
17127
  }
17053
- function amendmentKey(s, line2) {
17054
- return `${s}:${line2}`;
17128
+ function dialogueIdentity(s, id) {
17129
+ return `${s}\0${id}`;
17055
17130
  }
17056
17131
  function rangeDeclarationKey(range) {
17057
17132
  return JSON.stringify({
@@ -17102,7 +17177,8 @@ function undeclaredSessionRanges(prior, merged) {
17102
17177
  const out = [];
17103
17178
  for (let s = 0; s < merged.length; s += 1) {
17104
17179
  const session = merged[s];
17105
- const declared = priorKeys.get(physicalPathIdentity(session.path)) ?? /* @__PURE__ */ new Set();
17180
+ const identity = physicalPathIdentity(session.path);
17181
+ const declared = priorKeys.get(identity) ?? /* @__PURE__ */ new Set();
17106
17182
  const fresh = session.ranges.filter(
17107
17183
  (range) => !declared.has(rangeDeclarationKey(range))
17108
17184
  );
@@ -17120,36 +17196,61 @@ function undeclaredSessionRanges(prior, merged) {
17120
17196
  }
17121
17197
  return out;
17122
17198
  }
17123
- function compareLinePosition(left, right) {
17124
- if (left.s !== right.s) return left.s - right.s;
17125
- const leftLine = left.line ?? Number.MAX_SAFE_INTEGER;
17126
- const rightLine = right.line ?? Number.MAX_SAFE_INTEGER;
17127
- return leftLine - rightLine;
17128
- }
17129
17199
  function mergeFreshIntoCarried(carried, fresh) {
17130
- const seenIds = /* @__PURE__ */ new Set();
17131
- const seenPositions = /* @__PURE__ */ new Set();
17132
- const out = [];
17133
- for (const line2 of carried) {
17134
- if (line2.id !== void 0) seenIds.add(line2.id);
17135
- if (line2.line !== void 0)
17136
- seenPositions.add(amendmentKey(line2.s, line2.line));
17137
- out.push(line2);
17138
- }
17139
- for (const line2 of fresh) {
17140
- if (line2.id !== void 0) {
17141
- if (seenIds.has(line2.id)) continue;
17142
- seenIds.add(line2.id);
17200
+ const seenSources = /* @__PURE__ */ new Map();
17201
+ const bySession = /* @__PURE__ */ new Map();
17202
+ const absorb = (lines) => {
17203
+ for (const line2 of lines) {
17204
+ const sourceIdentity = line2.id === void 0 ? line2.sourceIdentity : `id\0${line2.id}`;
17205
+ const identity = sourceIdentity === void 0 ? void 0 : `${line2.s}\0${sourceIdentity}`;
17206
+ const seen = identity === void 0 ? void 0 : seenSources.get(identity);
17207
+ if (seen !== void 0) {
17208
+ if (line2.sourcePosition !== void 0) {
17209
+ Object.assign(seen, { sourcePosition: line2.sourcePosition });
17210
+ }
17211
+ continue;
17212
+ }
17213
+ const bucket = bySession.get(line2.s) ?? [];
17214
+ bucket.push({ ...line2 });
17215
+ if (identity !== void 0) seenSources.set(identity, bucket.at(-1));
17216
+ bySession.set(line2.s, bucket);
17217
+ }
17218
+ };
17219
+ absorb(carried);
17220
+ absorb(fresh);
17221
+ return [...bySession.entries()].sort(([left], [right]) => left - right).flatMap(([, lines]) => lines.map((line2, archiveIndex) => ({ line: line2, archiveIndex })).sort((left, right) => {
17222
+ const leftPosition = left.line.sourcePosition;
17223
+ const rightPosition = right.line.sourcePosition;
17224
+ if (leftPosition === void 0 && rightPosition === void 0) {
17225
+ return left.archiveIndex - right.archiveIndex;
17226
+ }
17227
+ if (leftPosition === void 0) return 1;
17228
+ if (rightPosition === void 0) return -1;
17229
+ return leftPosition - rightPosition || left.archiveIndex - right.archiveIndex;
17230
+ }).map(({ line: line2 }) => line2));
17231
+ }
17232
+ function stableSourceFacts(sessionLines) {
17233
+ const positionByIdentity = /* @__PURE__ */ new Map();
17234
+ const facts = [];
17235
+ let precedingId = "<start>";
17236
+ let idlessOffset = 0;
17237
+ for (const entry of sessionLines) {
17238
+ const id = entry.row === void 0 ? void 0 : nativeEventId(entry.row);
17239
+ if (id !== void 0) {
17240
+ precedingId = id;
17241
+ idlessOffset = 0;
17242
+ } else {
17243
+ idlessOffset += 1;
17143
17244
  }
17144
- if (line2.line !== void 0) {
17145
- const position = amendmentKey(line2.s, line2.line);
17146
- if (seenPositions.has(position)) continue;
17147
- seenPositions.add(position);
17245
+ const identity = id === void 0 ? `after\0${precedingId}\0${idlessOffset}` : `id\0${id}`;
17246
+ let position = positionByIdentity.get(identity);
17247
+ if (position === void 0) {
17248
+ position = positionByIdentity.size;
17249
+ positionByIdentity.set(identity, position);
17148
17250
  }
17149
- out.push(line2);
17251
+ facts.push({ position, identity });
17150
17252
  }
17151
- out.sort(compareLinePosition);
17152
- return out;
17253
+ return facts;
17153
17254
  }
17154
17255
  function normalizeResolvedRanges(ranges, sessionLines, sessionPath) {
17155
17256
  const resolved = [];
@@ -17201,9 +17302,14 @@ async function projectSessionRanges(input) {
17201
17302
  }
17202
17303
  const rows = sessionLines.map((entry) => entry.row);
17203
17304
  const dialogue = adaptSessionDialogue(rows);
17305
+ const sourceFacts = stableSourceFacts(sessionLines);
17306
+ const sourcePositionByIdentity = /* @__PURE__ */ new Map();
17307
+ for (const fact of sourceFacts) {
17308
+ sourcePositionByIdentity.set(fact.identity, fact.position);
17309
+ }
17204
17310
  const seenIds = input.seenIds;
17205
17311
  const lines = [];
17206
- const unparsable = [];
17312
+ const raw = [];
17207
17313
  const ranges = normalizeResolvedRanges(
17208
17314
  input.session.ranges,
17209
17315
  sessionLines,
@@ -17211,38 +17317,30 @@ async function projectSessionRanges(input) {
17211
17317
  );
17212
17318
  for (const range of ranges) {
17213
17319
  for (let index = range.fromIndex; index <= range.toIndex; index += 1) {
17320
+ const { position: sourcePosition, identity: sourceIdentity } = sourceFacts[index];
17321
+ if (input.coveredSourceIdentities.has(sourceIdentity) || input.legacyCoveredSourcePositions.has(sourcePosition)) continue;
17214
17322
  const entry = sessionLines[index];
17215
17323
  if (entry.row === void 0) {
17216
- const key = amendmentKey(input.s, entry.line);
17217
- const amendment = input.amendmentsByKey.get(key);
17218
- if (amendment !== void 0) {
17219
- lines.push({
17220
- speaker: amendment.speaker,
17221
- s: input.s,
17222
- line: entry.line,
17223
- text: amendment.text
17224
- });
17225
- } else {
17226
- unparsable.push({ s: input.s, line: entry.line, raw: entry.raw });
17227
- }
17324
+ raw.push({ raw: entry.raw, s: input.s, sourcePosition, sourceIdentity });
17228
17325
  continue;
17229
17326
  }
17230
17327
  for (const event of dialogue[index] ?? []) {
17231
17328
  if (event.id !== void 0) {
17232
- if (seenIds.has(event.id)) continue;
17233
- seenIds.add(event.id);
17329
+ const identity = dialogueIdentity(input.s, event.id);
17330
+ if (seenIds.has(identity)) continue;
17331
+ seenIds.add(identity);
17234
17332
  }
17235
17333
  lines.push({
17236
17334
  speaker: event.speaker,
17237
17335
  s: input.s,
17238
- line: entry.line,
17239
- ...event.id === void 0 ? {} : { id: event.id },
17336
+ sourcePosition,
17337
+ ...event.id === void 0 ? { sourceIdentity } : { id: event.id },
17240
17338
  text: event.text
17241
17339
  });
17242
17340
  }
17243
17341
  }
17244
17342
  }
17245
- return { lines, unparsable };
17343
+ return { lines, raw, sourcePositionByIdentity };
17246
17344
  }
17247
17345
  async function reprojectTicketProvenance(input) {
17248
17346
  const prior = await readTicketProvenance(input.ticketNumber, input.cwd, input.home);
@@ -17257,8 +17355,7 @@ async function reprojectTicketProvenance(input) {
17257
17355
  updatedAt: now2,
17258
17356
  sessions: []
17259
17357
  },
17260
- lines: prior.lines,
17261
- unparsable: []
17358
+ lines: prior.lines
17262
17359
  };
17263
17360
  }
17264
17361
  const merged = mergeSessionBounds(prior.header?.sessions, input.sessions);
@@ -17274,34 +17371,34 @@ async function reprojectTicketProvenance(input) {
17274
17371
  updatedAt: now2,
17275
17372
  sessions: merged.sessions
17276
17373
  },
17277
- lines: prior.lines,
17278
- unparsable: []
17374
+ lines: prior.lines
17279
17375
  };
17280
17376
  }
17281
- const amendmentsByKey = /* @__PURE__ */ new Map();
17282
- for (const amendment of input.amendments ?? []) {
17283
- const cumulativeIndex = merged.incomingIndexes[amendment.s];
17284
- if (cumulativeIndex === void 0) continue;
17285
- amendmentsByKey.set(amendmentKey(cumulativeIndex, amendment.line), {
17286
- ...amendment,
17287
- s: cumulativeIndex
17288
- });
17289
- }
17290
17377
  const seenIds = new Set(
17291
- prior.lines.flatMap((line2) => line2.id === void 0 ? [] : [line2.id])
17378
+ prior.lines.flatMap(
17379
+ (line2) => line2.id === void 0 ? [] : [dialogueIdentity(line2.s, line2.id)]
17380
+ )
17292
17381
  );
17293
17382
  const fresh = [];
17294
- const unparsable = [];
17383
+ const raw = [];
17295
17384
  for (const delta of deltas) {
17296
17385
  const projected = await projectSessionRanges({
17297
17386
  s: delta.s,
17298
17387
  session: delta.session,
17299
- amendmentsByKey,
17300
17388
  seenIds,
17389
+ coveredSourceIdentities: prior.sourceIdentities.get(delta.s) ?? /* @__PURE__ */ new Set(),
17390
+ legacyCoveredSourcePositions: prior.legacySourcePositions.get(delta.s) ?? /* @__PURE__ */ new Set(),
17301
17391
  ...input.home === void 0 ? {} : { home: input.home }
17302
17392
  });
17393
+ fresh.push(...prior.lines.flatMap((line2) => {
17394
+ if (line2.s !== delta.s) return [];
17395
+ const sourceIdentity = line2.id === void 0 ? line2.sourceIdentity : `id\0${line2.id}`;
17396
+ if (sourceIdentity === void 0) return [];
17397
+ const sourcePosition = projected.sourcePositionByIdentity.get(sourceIdentity);
17398
+ return sourcePosition === void 0 ? [] : [{ ...line2, sourcePosition }];
17399
+ }));
17303
17400
  fresh.push(...projected.lines);
17304
- unparsable.push(...projected.unparsable);
17401
+ raw.push(...projected.raw);
17305
17402
  }
17306
17403
  const lines = mergeFreshIntoCarried(prior.lines, fresh);
17307
17404
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -17312,9 +17409,6 @@ async function reprojectTicketProvenance(input) {
17312
17409
  updatedAt: now,
17313
17410
  sessions: merged.sessions
17314
17411
  };
17315
- if (unparsable.length > 0) {
17316
- return { recordFile: prior.recordFile, header, lines, unparsable };
17317
- }
17318
17412
  const identityMaterial = JSON.stringify({
17319
17413
  ticket: input.ticketNumber,
17320
17414
  deltas: deltas.map(({ s, session }) => ({
@@ -17322,7 +17416,7 @@ async function reprojectTicketProvenance(input) {
17322
17416
  path: physicalPathIdentity(session.path),
17323
17417
  ranges: session.ranges
17324
17418
  })),
17325
- lines: fresh
17419
+ lines: [...fresh, ...raw]
17326
17420
  });
17327
17421
  const identity = `ticket-provenance:${createHash8("sha256").update(identityMaterial).digest("hex")}`;
17328
17422
  const pointer = appendSitianRecord({
@@ -17331,15 +17425,14 @@ async function reprojectTicketProvenance(input) {
17331
17425
  payload: {
17332
17426
  type: "ticket-provenance-append",
17333
17427
  sessions: merged.sessions,
17334
- lines: fresh
17428
+ lines: [...fresh, ...raw]
17335
17429
  }
17336
17430
  });
17337
17431
  const folded = await readTicketProvenance(input.ticketNumber, input.cwd, input.home);
17338
17432
  return {
17339
17433
  recordFile: pointer.recordFile,
17340
17434
  header: folded.header ?? header,
17341
- lines: folded.lines,
17342
- unparsable: []
17435
+ lines: folded.lines
17343
17436
  };
17344
17437
  }
17345
17438
  var TicketProvenanceInputError;
@@ -20630,9 +20723,9 @@ import { randomUUID as randomUUID9 } from "node:crypto";
20630
20723
  // src/role-envelope.ts
20631
20724
  init_engine_detour();
20632
20725
  import { randomUUID as randomUUID8 } from "node:crypto";
20633
- import { mkdir as mkdir5, readFile as readFile20, writeFile as writeFile12 } from "node:fs/promises";
20726
+ import { mkdir as mkdir6, writeFile as writeFile12 } from "node:fs/promises";
20634
20727
  import { createServer } from "node:net";
20635
- import { basename as basename9, dirname as dirname21, join as join40 } from "node:path";
20728
+ import { dirname as dirname22, join as join41 } from "node:path";
20636
20729
  import { fileURLToPath as fileURLToPath2 } from "node:url";
20637
20730
 
20638
20731
  // src/gatekeeper-pass-envelope.ts
@@ -20717,9 +20810,43 @@ async function requireGatekeeperPass(options) {
20717
20810
  }
20718
20811
  }
20719
20812
 
20813
+ // src/host-native-method.ts
20814
+ import { lstat as lstat7, mkdir as mkdir5, readlink, realpath as realpath6, symlink } from "node:fs/promises";
20815
+ import { basename as basename9, dirname as dirname18, join as join36 } from "node:path";
20816
+ var packagedMethodsDir = (root) => join36(root, "resources", "methods");
20817
+ function hostMethodSkills(methods) {
20818
+ return Object.freeze(methods.flatMap((method) => {
20819
+ if (method.kind !== "skill") return [];
20820
+ const name = basename9(dirname18(method.path));
20821
+ return name ? [Object.freeze({ name })] : [];
20822
+ }));
20823
+ }
20824
+ async function installWorkspaceMethodSkills(cwd, packageRoot) {
20825
+ const target = await realpath6(packagedMethodsDir(packageRoot));
20826
+ const link = join36(cwd, ".agents", "skills");
20827
+ try {
20828
+ const stat2 = await lstat7(link);
20829
+ if (!stat2.isSymbolicLink() || await realpath6(link) !== target) {
20830
+ const detail = stat2.isSymbolicLink() ? `symlink to ${await readlink(link)}` : "non-symlink entry";
20831
+ throw new Error(`workspace method catalog conflict at ${link}: ${detail}`);
20832
+ }
20833
+ return;
20834
+ } catch (error) {
20835
+ if (error.code !== "ENOENT") throw error;
20836
+ }
20837
+ await mkdir5(dirname18(link), { recursive: true });
20838
+ try {
20839
+ await symlink(target, link);
20840
+ } catch (error) {
20841
+ if (error.code !== "EEXIST") throw error;
20842
+ if (await realpath6(link).catch(() => "") !== target) {
20843
+ throw new Error(`workspace method catalog conflict at ${link}`);
20844
+ }
20845
+ }
20846
+ }
20847
+
20720
20848
  // src/role-envelope.ts
20721
20849
  init_packaged_role_registry();
20722
- init_method_skill();
20723
20850
 
20724
20851
  // src/role-runtime.ts
20725
20852
  init_host_contracts();
@@ -20727,7 +20854,7 @@ init_sitian_facade();
20727
20854
  init_submission_ledger();
20728
20855
  init_collector_ledger();
20729
20856
  import { readFileSync as readFileSync6, writeSync as writeSync4 } from "node:fs";
20730
- import { join as join39 } from "node:path";
20857
+ import { join as join40 } from "node:path";
20731
20858
  import { Value as Value4 } from "typebox/value";
20732
20859
 
20733
20860
  // src/activation-trace.ts
@@ -20777,7 +20904,7 @@ import {
20777
20904
  openSync as openSync2,
20778
20905
  writeSync
20779
20906
  } from "node:fs";
20780
- import { dirname as dirname18, isAbsolute as isAbsolute10, resolve as resolve15 } from "node:path";
20907
+ import { dirname as dirname19, isAbsolute as isAbsolute10, resolve as resolve15 } from "node:path";
20781
20908
 
20782
20909
  // src/activation-ledger-session.ts
20783
20910
  init_activation_ledger_topology();
@@ -20926,7 +21053,7 @@ function appendActivationLedgerLine(ledgerPath, line2, options) {
20926
21053
  }
20927
21054
  const resolvedLedger = resolve15(ledgerPath);
20928
21055
  const resolvedHome = resolve15(options.ledgerHome);
20929
- const parent = dirname18(resolvedLedger);
21056
+ const parent = dirname19(resolvedLedger);
20930
21057
  ensureRealDirectoryTree(resolvedHome, parent);
20931
21058
  assertLedgerFileInsideHome(resolvedLedger, resolvedHome);
20932
21059
  if (typeof constants2.O_NOFOLLOW !== "number") {
@@ -21286,15 +21413,15 @@ init_collector_github();
21286
21413
 
21287
21414
  // src/collector-handbook.ts
21288
21415
  import { readFile as readFile19 } from "node:fs/promises";
21289
- import { join as join37, sep as sep5 } from "node:path";
21416
+ import { join as join38, sep as sep5 } from "node:path";
21290
21417
 
21291
21418
  // src/atomic-write.ts
21292
21419
  import { randomUUID as randomUUID7 } from "node:crypto";
21293
21420
  import { rename as rename3, rm as rm3, writeFile as writeFile11 } from "node:fs/promises";
21294
- import { dirname as dirname19, join as join36 } from "node:path";
21421
+ import { dirname as dirname20, join as join37 } from "node:path";
21295
21422
  async function writeFileAtomically(destination, contents) {
21296
- const parent = dirname19(destination);
21297
- const temporary = join36(parent, `.atomic-write-${randomUUID7()}.tmp`);
21423
+ const parent = dirname20(destination);
21424
+ const temporary = join37(parent, `.atomic-write-${randomUUID7()}.tmp`);
21298
21425
  try {
21299
21426
  await writeFile11(temporary, contents);
21300
21427
  await rename3(temporary, destination);
@@ -21420,7 +21547,7 @@ function resolveCollectorHandbookRoot(sessionPath) {
21420
21547
  throw new Error(`\u901A\u8FDB\u53F8\u624B\u518C\u62D2\u7EDD\u4E0D\u5B89\u5168 bookKey ${JSON.stringify(bookKey)}`);
21421
21548
  }
21422
21549
  const ledgerHome = resolveActivationLedgerHomeForPath(sessionPath);
21423
- const root = join37(activationBookDirectory(ledgerHome, bookKey), "collector-handbook");
21550
+ const root = join38(activationBookDirectory(ledgerHome, bookKey), "collector-handbook");
21424
21551
  return { ledgerHome, bookKey, root };
21425
21552
  }
21426
21553
  function collectorHandbookRepoFileName(repositoryCanonical) {
@@ -21432,9 +21559,9 @@ function collectorHandbookRepoFileName(repositoryCanonical) {
21432
21559
  return `${repositoryCanonical.replaceAll("/", "__")}.md`;
21433
21560
  }
21434
21561
  function createCollectorHandbookStore(input) {
21435
- const generalPath = join37(input.handbookRoot, "general.md");
21436
- const repoDir = join37(input.handbookRoot, "repos");
21437
- const repoPath = join37(repoDir, collectorHandbookRepoFileName(input.repositoryCanonical));
21562
+ const generalPath = join38(input.handbookRoot, "general.md");
21563
+ const repoDir = join38(input.handbookRoot, "repos");
21564
+ const repoPath = join38(repoDir, collectorHandbookRepoFileName(input.repositoryCanonical));
21438
21565
  const assertHandbookBudget = (body, label) => {
21439
21566
  const byteLength = Buffer.byteLength(body, "utf8");
21440
21567
  if (byteLength > COLLECTOR_HANDBOOK_MAX_BYTES) {
@@ -22417,33 +22544,6 @@ var diaristOutputSchema = withTerminatingOutputDeclarations(
22417
22544
  description: "\u672C\u7968\u5BF9\u8BDD\u8FB9\u754C\uFF1B\u7A7A\u5217\u8868\uFF1D\u672C\u8F6E\u65E0\u5BF9\u8BDD\u53EF\u5212\u3002\u7AEF\u70B9\u65E0\u6CD5\u6307\u540D\u65F6\u8D70 reask\uFF0C\u4E0D\u4E2D\u6B62\u3002"
22418
22545
  }
22419
22546
  )
22420
- ),
22421
- amendments: Type19.Optional(
22422
- Type19.Array(
22423
- Type19.Object(
22424
- {
22425
- s: Type19.Optional(
22426
- Type19.Unknown({ description: "\u5377\u4E0B\u6807\uFF08sessions \u4F4D\u7F6E\uFF09" })
22427
- ),
22428
- line: Type19.Optional(
22429
- Type19.Unknown({ description: "\u6E90\u5377 1-based \u884C\u53F7" })
22430
- ),
22431
- speaker: Type19.Optional(
22432
- Type19.String({ description: "owner | runner" })
22433
- ),
22434
- text: Type19.Optional(
22435
- Type19.String({ description: "\u8865\u5199\u6B63\u6587\uFF08\u539F\u8BDD\uFF09" })
22436
- )
22437
- },
22438
- {
22439
- additionalProperties: true,
22440
- description: "\u4E00\u6761\u574F\u884C\u8865\u5199\uFF1B\u7F3A\u5B57\u6BB5\u7684\u6210\u5458\u673A\u68B0\u8DF3\u8FC7"
22441
- }
22442
- ),
22443
- {
22444
- description: "\u53EF\u9009\uFF1B\u673A\u68B0\u89E3\u6790\u4E0D\u4E86\u7684\u884C\u4EA4\u6B64\u8865\u5199\u3002\u7F3A\u672C\u5B57\u6BB5\uFF1D\u65E0\u8865\u5199\uFF0C\u4E0D\u62D2\u6536\u3002"
22445
- }
22446
- )
22447
22547
  )
22448
22548
  })
22449
22549
  )
@@ -22451,8 +22551,8 @@ var diaristOutputSchema = withTerminatingOutputDeclarations(
22451
22551
  var DIARIST_TOOL_SPEC = {
22452
22552
  name: DIARIST_OUTPUT_TOOL_NAME,
22453
22553
  label: "\u8D77\u5C45\u90CE\u8F93\u51FA",
22454
- description: "\u8D77\u5C45\u90CE\u4EA4\u672C\u7968\u5BF9\u8BDD\u8FB9\u754C\uFF08sessions\uFF09\u4E0E\u53EF\u9009\u574F\u884C\u8865\u5199\uFF08amendments\uFF09\uFF1B\u8BA4\u4E0D\u51FA\u672C\u5EAD\u5BF9\u8C61\u5219 escalate\u3002",
22455
- promptSnippet: "\u8D77\u5C45\u90CE\u4EA4\u8FB9\u754C\u4E0E\u53EF\u9009\u8865\u5199",
22554
+ description: "\u8D77\u5C45\u90CE\u4EA4\u672C\u7968\u5BF9\u8BDD\u8FB9\u754C\uFF08sessions\uFF09\uFF1B\u8BA4\u4E0D\u51FA\u672C\u5EAD\u5BF9\u8C61\u5219 escalate\u3002",
22555
+ promptSnippet: "\u8D77\u5C45\u90CE\u4EA4\u8FB9\u754C",
22456
22556
  parameters: diaristOutputSchema
22457
22557
  };
22458
22558
 
@@ -22580,14 +22680,12 @@ async function commitDiaristProjection(input) {
22580
22680
  ticketNumber: input.ticketNumber,
22581
22681
  cwd: input.cwd,
22582
22682
  ...input.home === void 0 ? {} : { home: input.home },
22583
- sessions: input.sessions,
22584
- ...input.amendments === void 0 ? {} : { amendments: input.amendments }
22683
+ sessions: input.sessions
22585
22684
  });
22586
22685
  return {
22587
22686
  ticketNumber: input.ticketNumber,
22588
22687
  volumeRecordFile: result.recordFile,
22589
- lineCount: result.lines.length,
22590
- unparsable: result.unparsable
22688
+ lineCount: result.lines.length
22591
22689
  };
22592
22690
  }
22593
22691
 
@@ -24871,7 +24969,7 @@ function readDiaristTicketAssertion(submitted) {
24871
24969
  function readRoleRunCoordinates(ctx, label) {
24872
24970
  const runDirectory = runDirectoryFromHostContext(ctx);
24873
24971
  if (runDirectory === void 0) throw new Error(`${label} requires AK_ROLE_RUN_DIR`);
24874
- const admittedPath = join39(runDirectory, "admitted-request.json");
24972
+ const admittedPath = join40(runDirectory, "admitted-request.json");
24875
24973
  const admitted = JSON.parse(readFileSync6(admittedPath, "utf8"));
24876
24974
  if (typeof admitted.projectRoot !== "string" || admitted.projectRoot.trim() === "") {
24877
24975
  throw new Error(`${label} admitted-request missing projectRoot (${admittedPath})`);
@@ -24894,17 +24992,6 @@ function readDiaristRunCoordinates(ctx) {
24894
24992
  };
24895
24993
  }
24896
24994
  var DIARIST_BOUNDS_REASK = "\u8FB9\u754C\u65E0\u6CD5\u4F7F\u7528\u3002\u8BF7\u91CD\u4EA4 sessions\uFF1A\u6BCF\u5377 path + ranges\uFF0C\u6BCF\u7AEF\u4EE5\u539F\u751F id \u6216\u672C\u8F6E\u884C\u53F7\u4E8C\u9009\u4E00\u6307\u540D\u3002";
24897
- function diaristUnparsableReask(rows) {
24898
- const payload = rows.map((row) => ({
24899
- s: row.s,
24900
- line: row.line,
24901
- raw: row.raw
24902
- }));
24903
- return [
24904
- "\u4E0B\u5217\u6E90\u884C\u672A\u80FD\u5F55\u5165\uFF0C\u8BF7\u7ECF amendments \u8865\u5199\uFF08\u6BCF\u6761 s + line + speaker + text\uFF09\uFF1B\u5176\u4F59\u8FB9\u754C\u53EF\u4FDD\u6301\u4E0D\u53D8\u3002",
24905
- JSON.stringify(payload)
24906
- ].join("\n");
24907
- }
24908
24995
  function createDiaristRoleRuntime(roleHost, dependencies) {
24909
24996
  return createFiledOfficerRuntime(
24910
24997
  roleHost,
@@ -24926,15 +25013,13 @@ function createDiaristRoleRuntime(roleHost, dependencies) {
24926
25013
  if (sessions === void 0) {
24927
25014
  throw new ParentQueueReaskError(DIARIST_BOUNDS_REASK);
24928
25015
  }
24929
- const amendments = projectDiaristAmendments(parameters);
24930
25016
  let facts;
24931
25017
  try {
24932
25018
  facts = await commitDiaristProjection({
24933
25019
  ticketNumber,
24934
25020
  cwd: coords.projectRoot,
24935
25021
  home: coords.home,
24936
- sessions,
24937
- amendments
25022
+ sessions
24938
25023
  });
24939
25024
  } catch (error) {
24940
25025
  if (error instanceof ParentQueueReaskError) throw error;
@@ -24946,9 +25031,6 @@ ${error.message}`
24946
25031
  }
24947
25032
  throw error;
24948
25033
  }
24949
- if (facts.unparsable.length > 0) {
24950
- throw new ParentQueueReaskError(diaristUnparsableReask(facts.unparsable));
24951
- }
24952
25034
  }
24953
25035
  return parameters;
24954
25036
  }
@@ -25120,6 +25202,7 @@ function createRoleRuntimeExtension(dependencies) {
25120
25202
  });
25121
25203
  let admitted = false;
25122
25204
  let selectedRole;
25205
+ let roleReferenceMaterials = "";
25123
25206
  let activeReviewerParent;
25124
25207
  let reviewerOriginalRequest;
25125
25208
  let reviewerExpansionCaptured = false;
@@ -25213,10 +25296,10 @@ function createRoleRuntimeExtension(dependencies) {
25213
25296
  activeReviewerParent.skillBinding.name,
25214
25297
  text
25215
25298
  ) ?? text;
25216
- return text === event.text ? { action: "continue" } : { action: "transform", text };
25217
25299
  }
25218
- return text === event.text ? { action: "continue" } : { action: "transform", text };
25300
+ return { action: "continue" };
25219
25301
  });
25302
+ roleHost.on("before_agent_start", () => roleReferenceMaterials === "" ? void 0 : { readingMaterial: { kind: "role-reference-materials", content: roleReferenceMaterials } });
25220
25303
  roleHost.on("before_agent_start", async (event, ctx) => {
25221
25304
  const role = roleHost.getFlag(ROLE_FLAG.name);
25222
25305
  const prompt = event.prompt;
@@ -25782,6 +25865,7 @@ function createRoleRuntimeExtension(dependencies) {
25782
25865
  }
25783
25866
  admitted = false;
25784
25867
  selectedRole = void 0;
25868
+ roleReferenceMaterials = "";
25785
25869
  activeReviewerParent = void 0;
25786
25870
  reviewerOriginalRequest = void 0;
25787
25871
  reviewerExpansionCaptured = false;
@@ -25916,6 +26000,7 @@ function createRoleRuntimeExtension(dependencies) {
25916
26000
  }
25917
26001
  }
25918
26002
  await executeActivationStage(entry.role, activationStage(entry.role, runtime), { clock, writeTrace });
26003
+ roleReferenceMaterials = await dependencies.loadRoleReferenceMaterials?.(entry.role) ?? "";
25919
26004
  if (!engineDetourRegistered) {
25920
26005
  engineDetourRegistered = registerEngineDetourTool(roleHost, hostActions);
25921
26006
  }
@@ -25950,19 +26035,6 @@ function createRoleRuntimeExtension(dependencies) {
25950
26035
  init_role_activation_flags();
25951
26036
  init_submission_correctable_error();
25952
26037
  init_navigator_invocation_identity();
25953
- function buildSkillExpansion(methodSkills, prompt) {
25954
- if (methodSkills.size !== 1) return void 0;
25955
- const entry = methodSkills.entries().next().value;
25956
- if (entry === void 0) return void 0;
25957
- const [name, method] = entry;
25958
- return Object.freeze({
25959
- name,
25960
- location: method.path,
25961
- content: method.body,
25962
- // Non-pi typed chain keeps original task bytes (ticket #822 r3); no consumer trim.
25963
- userMessage: prompt
25964
- });
25965
- }
25966
26038
  async function listen(server, path) {
25967
26039
  await new Promise((resolve21, reject) => {
25968
26040
  server.once("error", reject);
@@ -25997,21 +26069,14 @@ async function prepareRoleEnvelope(options) {
25997
26069
  const calls = [];
25998
26070
  const customEntries = [];
25999
26071
  const sessionEntries = [];
26000
- const methodSkills = /* @__PURE__ */ new Map();
26001
26072
  let preferredTools = [];
26002
26073
  let rejection;
26003
26074
  let infrastructureRoundFailure;
26004
26075
  const hostAbort = new AbortController();
26005
26076
  const runId = request.runDirectory.split("/").filter(Boolean).at(-1) ?? randomUUID8();
26006
- await mkdir5(request.runDirectory, { recursive: true });
26007
- for (const method of request.methods) {
26008
- if (method.kind !== "skill") continue;
26009
- const name = basename9(dirname21(method.path));
26010
- const raw = await readFile20(method.path, "utf8");
26011
- methodSkills.set(name, { path: method.path, body: stripSkillFrontmatter(raw).trim() });
26012
- }
26013
- let sessionFile = options.sessionFile ?? join40(request.runDirectory, "session", "session.jsonl");
26014
- await mkdir5(dirname21(sessionFile), { recursive: true });
26077
+ await mkdir6(request.runDirectory, { recursive: true });
26078
+ let sessionFile = options.sessionFile ?? join41(request.runDirectory, "session", "session.jsonl");
26079
+ await mkdir6(dirname22(sessionFile), { recursive: true });
26015
26080
  if (request.continuation.kind !== "resume") {
26016
26081
  try {
26017
26082
  await writeFile12(
@@ -26042,7 +26107,7 @@ async function prepareRoleEnvelope(options) {
26042
26107
  getLeafEntry: () => sessionEntries.at(-1),
26043
26108
  getLeafId: () => runId,
26044
26109
  getEntries: () => sessionEntries,
26045
- getSessionDir: () => dirname21(sessionFile),
26110
+ getSessionDir: () => dirname22(sessionFile),
26046
26111
  getSessionFile: () => sessionFile,
26047
26112
  getHeader: () => ({ type: "session", id: runId }),
26048
26113
  setSessionFile(path) {
@@ -26077,8 +26142,9 @@ async function prepareRoleEnvelope(options) {
26077
26142
  deliverSubmissionRejection(_value) {
26078
26143
  },
26079
26144
  capabilities: {
26080
- skillExpansion(prompt) {
26081
- return buildSkillExpansion(methodSkills, prompt);
26145
+ // #922: native loaders own expansion; package does not pre-read bodies (ADR 0032).
26146
+ skillExpansion() {
26147
+ return void 0;
26082
26148
  }
26083
26149
  },
26084
26150
  registerFlag(name, definition) {
@@ -26417,10 +26483,9 @@ async function prepareRoleEnvelope(options) {
26417
26483
  message: { role: "user", content: prompt }
26418
26484
  });
26419
26485
  }
26420
- const methodPrompt = (await Promise.all(request.methods.map(({ path }) => readFile20(path, "utf8")))).join("\n\n");
26421
26486
  const promptResults = await emit("before_agent_start", {
26422
26487
  prompt,
26423
- systemPrompt: methodPrompt,
26488
+ systemPrompt: "",
26424
26489
  systemPromptOptions: {}
26425
26490
  });
26426
26491
  const systemPromptParts = promptResults.flatMap((value) => {
@@ -26428,7 +26493,7 @@ async function prepareRoleEnvelope(options) {
26428
26493
  if (!("systemPrompt" in value) || typeof value.systemPrompt !== "string") return [];
26429
26494
  return [value.systemPrompt];
26430
26495
  });
26431
- const systemPromptBody = systemPromptParts.length > 0 ? systemPromptParts.join("\n\n") : methodPrompt;
26496
+ const systemPromptBody = systemPromptParts.join("\n\n");
26432
26497
  const readingMaterials = [];
26433
26498
  for (const value of promptResults) {
26434
26499
  if (typeof value !== "object" || value === null) continue;
@@ -26441,6 +26506,13 @@ async function prepareRoleEnvelope(options) {
26441
26506
  throw new Error(`terminating tool not registered after activation: ${terminatingToolName}`);
26442
26507
  }
26443
26508
  const jsonSchema = terminatingToolJsonSchema(terminating.parameters);
26509
+ if (request.host === "codex" && hostMethodSkills(request.methods).length > 0) {
26510
+ const packageRoot = options.dependencies.packageRoot;
26511
+ if (typeof packageRoot !== "string" || packageRoot === "") {
26512
+ throw new Error("codex project Skill catalog requires packageRoot");
26513
+ }
26514
+ await installWorkspaceMethodSkills(request.cwd, packageRoot);
26515
+ }
26444
26516
  return {
26445
26517
  mcpServers: [{
26446
26518
  name: `ak-${request.activation.role}`,
@@ -26475,18 +26547,18 @@ async function prepareRoleEnvelope(options) {
26475
26547
  }
26476
26548
 
26477
26549
  // src/role-runtime-dependencies.ts
26478
- import { readFile as readFile23 } from "node:fs/promises";
26550
+ import { readFile as readFile22 } from "node:fs/promises";
26479
26551
  import { fileURLToPath as fileURLToPath3 } from "node:url";
26480
26552
 
26481
26553
  // src/canonical-skill-binding.ts
26482
- import { readFile as readFile21, realpath as realpath6 } from "node:fs/promises";
26554
+ import { readFile as readFile20, realpath as realpath7 } from "node:fs/promises";
26483
26555
  import { homedir } from "node:os";
26484
- import { dirname as dirname22, resolve as resolve18 } from "node:path";
26556
+ import { dirname as dirname23, resolve as resolve18 } from "node:path";
26485
26557
  import { stripFrontmatter } from "@earendil-works/pi-coding-agent";
26486
26558
  function captureCanonicalSkillExpansion(name, snapshot, configuredPath, evidence, originalRequest) {
26487
26559
  const matchedPath = evidence?.location === configuredPath ? configuredPath : evidence?.location === snapshot.path ? snapshot.path : void 0;
26488
26560
  const expectedContent = matchedPath === void 0 ? void 0 : snapshot.body;
26489
- const prefixedContent = matchedPath === void 0 ? void 0 : `References are relative to ${dirname22(matchedPath)}.
26561
+ const prefixedContent = matchedPath === void 0 ? void 0 : `References are relative to ${dirname23(matchedPath)}.
26490
26562
 
26491
26563
  ${snapshot.body}`;
26492
26564
  if (evidence?.name !== name || matchedPath === void 0 || evidence.content !== expectedContent && evidence.content !== prefixedContent || evidence.userMessage !== originalRequest) {
@@ -26511,8 +26583,8 @@ async function loadCanonicalSkillBinding(name) {
26511
26583
  let path;
26512
26584
  let raw;
26513
26585
  try {
26514
- path = await realpath6(configuredPath);
26515
- raw = await readFile21(path, "utf8");
26586
+ path = await realpath7(configuredPath);
26587
+ raw = await readFile20(path, "utf8");
26516
26588
  } catch (error) {
26517
26589
  throw new CanonicalSkillUnavailableError(name, configuredPath, error);
26518
26590
  }
@@ -26523,7 +26595,7 @@ async function loadCanonicalSkillBinding(name) {
26523
26595
  const snapshot = Object.freeze({
26524
26596
  raw,
26525
26597
  path,
26526
- baseDir: dirname22(path),
26598
+ baseDir: dirname23(path),
26527
26599
  body,
26528
26600
  snapshotIdentity: Object.freeze({ text: raw })
26529
26601
  });
@@ -26551,7 +26623,7 @@ init_doctor_evidence();
26551
26623
  // src/navigator-work-context.ts
26552
26624
  init_doctor_evidence();
26553
26625
  init_host_contracts();
26554
- import { readFile as readFile22 } from "node:fs/promises";
26626
+ import { readFile as readFile21 } from "node:fs/promises";
26555
26627
  import { resolve as resolve19 } from "node:path";
26556
26628
  init_notary_source_run();
26557
26629
  init_packaged_role_registry();
@@ -26564,7 +26636,7 @@ function navigatorInputReference(getFlag, role) {
26564
26636
  }
26565
26637
  async function loadNavigatorWorkContext(options) {
26566
26638
  const reference = navigatorInputReference(options.getFlag, options.role);
26567
- const input = reference === void 0 || options.role === "doctor" || options.role === "notary" ? void 0 : await readFile22(reference, "utf8");
26639
+ const input = reference === void 0 || options.role === "doctor" || options.role === "notary" ? void 0 : await readFile21(reference, "utf8");
26568
26640
  const subjectRoot = subjectPath(reference ?? options.context.sessionManager.getSessionDir(), options.context.cwd);
26569
26641
  let subjectKey = reference === void 0 ? subjectRoot : navigatorSubjectKeyForInput(subjectRoot, reference, options.context.cwd);
26570
26642
  let subject = input ?? `work subject: ${subjectKey}`;
@@ -26621,7 +26693,7 @@ async function loadNavigatorWorkContext(options) {
26621
26693
  let authorityMaterial;
26622
26694
  for (const path of authorityFiles) {
26623
26695
  try {
26624
- const content = await readFile22(path, "utf8");
26696
+ const content = await readFile21(path, "utf8");
26625
26697
  if (content.trim() !== "") {
26626
26698
  authorityMaterial = content;
26627
26699
  break;
@@ -26646,7 +26718,7 @@ async function loadNavigatorWorkContext(options) {
26646
26718
  init_notary_source_run();
26647
26719
 
26648
26720
  // src/package-resources/method-skill-binding.ts
26649
- import { dirname as dirname23 } from "node:path";
26721
+ import { dirname as dirname24 } from "node:path";
26650
26722
  init_method_skill();
26651
26723
  async function loadPackagedCanonicalSkillBinding(packageRoot, name) {
26652
26724
  const material = await loadPackagedMethodSkillMaterial(packageRoot, name);
@@ -26654,7 +26726,7 @@ async function loadPackagedCanonicalSkillBinding(packageRoot, name) {
26654
26726
  const snapshot = Object.freeze({
26655
26727
  raw: material.raw,
26656
26728
  path: material.skillPath,
26657
- baseDir: dirname23(material.skillPath),
26729
+ baseDir: dirname24(material.skillPath),
26658
26730
  body: material.body,
26659
26731
  snapshotIdentity: Object.freeze({ text: material.raw })
26660
26732
  });
@@ -26683,19 +26755,23 @@ var navigatorRoutePlaybookPath = fileURLToPath3(
26683
26755
  var collectorHandbookSeedPath = fileURLToPath3(
26684
26756
  new URL("../resources/collector-bot-handbook.md", import.meta.url)
26685
26757
  );
26758
+ function loadPackagedRoleReferenceMaterials(role) {
26759
+ return role === "auditor" ? loadAuditorReferenceMaterialsFromSubjectInput() : loadMainRoleReferenceMaterials(role);
26760
+ }
26686
26761
  function createRoleRuntimeDependencies(packageRoot) {
26687
26762
  const doctorAuditor = createPiDoctorAuditor();
26688
26763
  const navigatorSessionFactory = createNativeNavigatorSessionFactory();
26689
26764
  return {
26690
26765
  packageRoot,
26766
+ loadRoleReferenceMaterials: loadPackagedRoleReferenceMaterials,
26691
26767
  loadJudgeSoul: () => loadMainRoleSessionMaterials("judge"),
26692
26768
  loadFixerSoul: () => loadMainRoleSessionMaterials("fixer"),
26693
- loadFixPacket: (path) => readFile23(path, "utf8"),
26769
+ loadFixPacket: (path) => readFile22(path, "utf8"),
26694
26770
  loadCoderSoul: () => loadMainRoleSessionMaterials("coder"),
26695
- loadCoderTask: (path) => readFile23(path, "utf8"),
26771
+ loadCoderTask: (path) => readFile22(path, "utf8"),
26696
26772
  loadReviewerSoul: () => loadMainRoleSessionMaterials("reviewer"),
26697
26773
  loadCollectorSoul: () => loadMainRoleSessionMaterials("collector"),
26698
- loadCollectorHandbookSeed: () => readFile23(collectorHandbookSeedPath, "utf8"),
26774
+ loadCollectorHandbookSeed: () => readFile22(collectorHandbookSeedPath, "utf8"),
26699
26775
  createCollectorTransport: () => createGhCollectorGitHubTransport(),
26700
26776
  loadDoctorSoul: () => loadMainRoleSessionMaterials("doctor"),
26701
26777
  loadDoctorCase,
@@ -26710,7 +26786,7 @@ function createRoleRuntimeDependencies(packageRoot) {
26710
26786
  loadSecretariatSoul: () => loadMainRoleSessionMaterials("secretariat"),
26711
26787
  loadNotarySourceRun: loadNotarySourceRunLocator,
26712
26788
  loadMergerSoul: () => loadMainRoleSessionMaterials("merger"),
26713
- loadMergerInput: async (path) => JSON.parse(await readFile23(path, "utf8")),
26789
+ loadMergerInput: async (path) => JSON.parse(await readFile22(path, "utf8")),
26714
26790
  async loadCanonicalSkillBinding(name) {
26715
26791
  if (name === "tdd") {
26716
26792
  return loadPackagedCanonicalSkillBinding(packageRoot, "tdd");
@@ -26736,7 +26812,7 @@ function createRoleRuntimeDependencies(packageRoot) {
26736
26812
  authority: options.authority,
26737
26813
  invocationId: options.invocationId,
26738
26814
  loadSoul: () => loadMainRoleSessionMaterials("navigator"),
26739
- loadRoutePlaybook: () => readFile23(navigatorRoutePlaybookPath, "utf8"),
26815
+ loadRoutePlaybook: () => readFile22(navigatorRoutePlaybookPath, "utf8"),
26740
26816
  loadRoleHelp: async (role) => formatNavigatorRoleHelp(role),
26741
26817
  createSession: navigatorSessionFactory,
26742
26818
  ...options.contextError === void 0 ? {} : { contextError: options.contextError },
@@ -26749,9 +26825,9 @@ function createRoleRuntimeDependencies(packageRoot) {
26749
26825
  init_session_identity();
26750
26826
 
26751
26827
  // src/acp-host/description.ts
26752
- import { join as join41 } from "node:path";
26828
+ import { join as join42 } from "node:path";
26753
26829
  function resolveAcpBinary(description, operatorHome) {
26754
- return join41(operatorHome, ...description.binaryFromHome);
26830
+ return join42(operatorHome, ...description.binaryFromHome);
26755
26831
  }
26756
26832
  function acpStdioArgs(description, model, seat) {
26757
26833
  const { prefix, suffix, modelFlag, thinkingFlag } = description.argv;
@@ -27197,13 +27273,13 @@ function createAcpRoleTurnHost(config) {
27197
27273
 
27198
27274
  // src/acp-host/seat-profile-soul.ts
27199
27275
  import { constants as constants3 } from "node:fs";
27200
- import { access as access4, copyFile, lstat as lstat7, mkdir as mkdir6, readlink, symlink, unlink as unlink3 } from "node:fs/promises";
27201
- import { dirname as dirname24, join as join42, relative as relative3, resolve as resolve20 } from "node:path";
27276
+ import { access as access4, copyFile, lstat as lstat8, mkdir as mkdir7, readlink as readlink2, symlink as symlink2, unlink as unlink3 } from "node:fs/promises";
27277
+ import { dirname as dirname25, join as join43, relative as relative3, resolve as resolve20 } from "node:path";
27202
27278
  function seatProfileName(spec, role) {
27203
27279
  return `${spec.namePrefix}${role}`;
27204
27280
  }
27205
27281
  function packageRoleSoulPath(packageRoot, role) {
27206
- return join42(packageRoot, "souls", `${role}.md`);
27282
+ return join43(packageRoot, "souls", `${role}.md`);
27207
27283
  }
27208
27284
  async function pathExists2(path) {
27209
27285
  try {
@@ -27220,26 +27296,26 @@ async function ensureSeatProfileSoul(options) {
27220
27296
  if (!await pathExists2(soulTarget)) {
27221
27297
  throw new Error(`packaged role soul missing: ${soulTarget}`);
27222
27298
  }
27223
- const profilesRoot = join42(operatorHome, ...spec.profilesRootFromHome);
27224
- const profileDir = join42(profilesRoot, profileName);
27225
- const hostRoot = dirname24(profilesRoot);
27226
- const soulPath = join42(profileDir, spec.soulFileName);
27299
+ const profilesRoot = join43(operatorHome, ...spec.profilesRootFromHome);
27300
+ const profileDir = join43(profilesRoot, profileName);
27301
+ const hostRoot = dirname25(profilesRoot);
27302
+ const soulPath = join43(profileDir, spec.soulFileName);
27227
27303
  if (!await pathExists2(profileDir)) {
27228
- await mkdir6(profileDir, { recursive: true });
27304
+ await mkdir7(profileDir, { recursive: true });
27229
27305
  for (const name of ["auth.json", ".env", "config.yaml"]) {
27230
- const source = join42(hostRoot, name);
27306
+ const source = join43(hostRoot, name);
27231
27307
  if (!await pathExists2(source)) continue;
27232
- await copyFile(source, join42(profileDir, name));
27308
+ await copyFile(source, join43(profileDir, name));
27233
27309
  }
27234
27310
  } else {
27235
- await mkdir6(profileDir, { recursive: true });
27311
+ await mkdir7(profileDir, { recursive: true });
27236
27312
  }
27237
27313
  const desiredLink = relative3(profileDir, soulTarget);
27238
27314
  let current;
27239
27315
  try {
27240
- const st = await lstat7(soulPath);
27316
+ const st = await lstat8(soulPath);
27241
27317
  if (st.isSymbolicLink()) {
27242
- current = await readlink(soulPath);
27318
+ current = await readlink2(soulPath);
27243
27319
  }
27244
27320
  } catch {
27245
27321
  current = void 0;
@@ -27250,7 +27326,7 @@ async function ensureSeatProfileSoul(options) {
27250
27326
  if (await pathExists2(soulPath) || current !== void 0) {
27251
27327
  await unlink3(soulPath);
27252
27328
  }
27253
- await symlink(desiredLink, soulPath);
27329
+ await symlink2(desiredLink, soulPath);
27254
27330
  return profileName;
27255
27331
  }
27256
27332
 
@@ -27270,7 +27346,6 @@ function createProductionAcpRoleTurnHost(options) {
27270
27346
  const { packageRoot, principalAuthority, description, hostName } = options;
27271
27347
  const env = {
27272
27348
  ...process.env,
27273
- ...description.childEnv,
27274
27349
  AK_PACKAGE_ROOT: packageRoot
27275
27350
  };
27276
27351
  return createComposedAcpRoleTurnHost({