harnery 0.45.2 → 0.46.0

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 (216) hide show
  1. package/dist/commander.d.ts +13 -0
  2. package/dist/commander.d.ts.map +1 -1
  3. package/dist/commands/admission.d.ts.map +1 -1
  4. package/dist/commands/admission.js +214 -27
  5. package/dist/commands/agents.d.ts +4 -0
  6. package/dist/commands/agents.d.ts.map +1 -1
  7. package/dist/commands/agents.js +102 -25
  8. package/dist/commands/browse.d.ts +3 -0
  9. package/dist/commands/browse.d.ts.map +1 -1
  10. package/dist/commands/browse.js +172 -8
  11. package/dist/commands/fetch.js +1 -0
  12. package/dist/commands/ledger-v3.d.ts.map +1 -1
  13. package/dist/commands/ledger-v3.js +8 -2
  14. package/dist/commands/presence.d.ts.map +1 -1
  15. package/dist/commands/presence.js +40 -0
  16. package/dist/commands/qa-run.d.ts.map +1 -1
  17. package/dist/commands/qa-run.js +4 -3
  18. package/dist/commands/review-pack.d.ts.map +1 -1
  19. package/dist/commands/review-pack.js +33 -6
  20. package/dist/core/agents/index.d.ts +1 -0
  21. package/dist/core/agents/index.d.ts.map +1 -1
  22. package/dist/core/agents/index.js +1 -0
  23. package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
  24. package/dist/core/agents/live-authority-v3.js +11 -4
  25. package/dist/core/agents/render/session-context.d.ts +0 -6
  26. package/dist/core/agents/render/session-context.d.ts.map +1 -1
  27. package/dist/core/agents/render/session-context.js +1 -6
  28. package/dist/core/agents/session-events.d.ts.map +1 -1
  29. package/dist/core/agents/session-events.js +12 -4
  30. package/dist/core/agents/state/heartbeat-reader.d.ts +3 -0
  31. package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
  32. package/dist/core/agents/state/live-coordination-view.d.ts +3 -1
  33. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  34. package/dist/core/agents/state/live-coordination-view.js +6 -2
  35. package/dist/core/agents/state/parent-reference-contract.d.ts +16 -0
  36. package/dist/core/agents/state/parent-reference-contract.d.ts.map +1 -0
  37. package/dist/core/agents/state/parent-reference-contract.js +1 -0
  38. package/dist/core/agents/state/parent-reference.d.ts +18 -0
  39. package/dist/core/agents/state/parent-reference.d.ts.map +1 -0
  40. package/dist/core/agents/state/parent-reference.js +119 -0
  41. package/dist/core/config.d.ts +39 -0
  42. package/dist/core/config.d.ts.map +1 -1
  43. package/dist/core/config.js +63 -0
  44. package/dist/core/diagnostics/path-identity.d.ts +1 -1
  45. package/dist/core/diagnostics/path-identity.d.ts.map +1 -1
  46. package/dist/core/diagnostics/path-identity.js +51 -6
  47. package/dist/core/events/v3/canonical.js +43 -14
  48. package/dist/core/events/v3/index.d.ts +1 -1
  49. package/dist/core/events/v3/index.d.ts.map +1 -1
  50. package/dist/core/events/v3/index.js +1 -1
  51. package/dist/core/events/v3/producers/recorder.d.ts +34 -0
  52. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  53. package/dist/core/events/v3/producers/recorder.js +117 -13
  54. package/dist/core/events/v3/reader.d.ts.map +1 -1
  55. package/dist/core/events/v3/reader.js +53 -13
  56. package/dist/core/events/v3/validate.d.ts.map +1 -1
  57. package/dist/core/events/v3/validate.js +36 -1
  58. package/dist/core/hooks/adapter/native-parent.d.ts +23 -0
  59. package/dist/core/hooks/adapter/native-parent.d.ts.map +1 -0
  60. package/dist/core/hooks/adapter/native-parent.js +91 -0
  61. package/dist/core/hooks/cli.js +79 -4
  62. package/dist/core/hooks/resolve/owner.d.ts +0 -11
  63. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  64. package/dist/core/hooks/resolve/owner.js +0 -23
  65. package/dist/core/hooks/shell-admission.d.ts +84 -0
  66. package/dist/core/hooks/shell-admission.d.ts.map +1 -0
  67. package/dist/core/hooks/shell-admission.js +622 -0
  68. package/dist/core/hooks/shell-commit-tree.d.ts +2 -0
  69. package/dist/core/hooks/shell-commit-tree.d.ts.map +1 -0
  70. package/dist/core/hooks/shell-commit-tree.js +104 -0
  71. package/dist/core/inbox/contract.d.ts +12 -0
  72. package/dist/core/inbox/contract.d.ts.map +1 -1
  73. package/dist/core/inbox/contract.js +16 -0
  74. package/dist/core/inbox/peer-messages.d.ts +41 -16
  75. package/dist/core/inbox/peer-messages.d.ts.map +1 -1
  76. package/dist/core/inbox/peer-messages.js +372 -15
  77. package/dist/core/inbox/service.d.ts +8 -1
  78. package/dist/core/inbox/service.d.ts.map +1 -1
  79. package/dist/core/inbox/service.js +83 -3
  80. package/dist/core/inbox/targets.d.ts +17 -3
  81. package/dist/core/inbox/targets.d.ts.map +1 -1
  82. package/dist/core/inbox/targets.js +77 -2
  83. package/dist/core/presence/git.d.ts +18 -12
  84. package/dist/core/presence/git.d.ts.map +1 -1
  85. package/dist/core/presence/git.js +32 -38
  86. package/dist/core/presence/index.d.ts +2 -2
  87. package/dist/core/presence/index.d.ts.map +1 -1
  88. package/dist/core/presence/index.js +8 -6
  89. package/dist/core/presence/mail.d.ts +133 -0
  90. package/dist/core/presence/mail.d.ts.map +1 -0
  91. package/dist/core/presence/mail.js +464 -0
  92. package/dist/core/semantic/contract.d.ts +5 -5
  93. package/dist/core/storage/modes.d.ts +4 -0
  94. package/dist/core/storage/modes.d.ts.map +1 -1
  95. package/dist/core/storage/modes.js +4 -0
  96. package/dist/core/storage/segments.d.ts.map +1 -1
  97. package/dist/core/storage/segments.js +5 -4
  98. package/dist/lib/admission-history.d.ts +96 -0
  99. package/dist/lib/admission-history.d.ts.map +1 -0
  100. package/dist/lib/admission-history.js +196 -0
  101. package/dist/lib/admission.d.ts +56 -7
  102. package/dist/lib/admission.d.ts.map +1 -1
  103. package/dist/lib/admission.js +161 -19
  104. package/dist/lib/browser/client.d.ts +18 -0
  105. package/dist/lib/browser/client.d.ts.map +1 -1
  106. package/dist/lib/browser/client.js +100 -12
  107. package/dist/lib/browser/content-checks.d.ts +3 -1
  108. package/dist/lib/browser/content-checks.d.ts.map +1 -1
  109. package/dist/lib/browser/content-checks.js +10 -2
  110. package/dist/lib/browser/critique.d.ts +32 -0
  111. package/dist/lib/browser/critique.d.ts.map +1 -1
  112. package/dist/lib/browser/critique.js +72 -3
  113. package/dist/lib/browser/geometry.d.ts +2 -0
  114. package/dist/lib/browser/geometry.d.ts.map +1 -1
  115. package/dist/lib/browser/geometry.js +61 -15
  116. package/dist/lib/browser/index.d.ts +1 -1
  117. package/dist/lib/browser/index.d.ts.map +1 -1
  118. package/dist/lib/browser/index.js +1 -1
  119. package/dist/lib/browser/page-review-contracts.d.ts +6 -1
  120. package/dist/lib/browser/page-review-contracts.d.ts.map +1 -1
  121. package/dist/lib/browser/page-review-contracts.js +6 -1
  122. package/dist/lib/browser/page-review-judge.d.ts +3 -1
  123. package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
  124. package/dist/lib/browser/page-review-judge.js +41 -11
  125. package/dist/lib/browser/page-review-pack.d.ts +3 -0
  126. package/dist/lib/browser/page-review-pack.d.ts.map +1 -1
  127. package/dist/lib/browser/page-review-pack.js +5 -2
  128. package/dist/lib/browser/qa-run-contracts.d.ts +11 -0
  129. package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
  130. package/dist/lib/browser/qa-run-contracts.js +11 -4
  131. package/dist/lib/browser/qa-run.d.ts.map +1 -1
  132. package/dist/lib/browser/qa-run.js +73 -16
  133. package/dist/lib/browser/runts.d.ts +4 -2
  134. package/dist/lib/browser/runts.d.ts.map +1 -1
  135. package/dist/lib/browser/runts.js +84 -33
  136. package/dist/lib/browser/windows-chrome.d.ts +14 -0
  137. package/dist/lib/browser/windows-chrome.d.ts.map +1 -1
  138. package/dist/lib/browser/windows-chrome.js +42 -0
  139. package/dist/lib/browser/windows-login-sync.d.ts +110 -0
  140. package/dist/lib/browser/windows-login-sync.d.ts.map +1 -0
  141. package/dist/lib/browser/windows-login-sync.js +171 -0
  142. package/dist/lib/cookies/client.d.ts +30 -5
  143. package/dist/lib/cookies/client.d.ts.map +1 -1
  144. package/dist/lib/cookies/client.js +55 -10
  145. package/dist/lib/cookies/index.d.ts +1 -1
  146. package/dist/lib/cookies/index.d.ts.map +1 -1
  147. package/dist/lib/cookies/index.js +1 -1
  148. package/dist/lib/docs-metadata-sync.d.ts.map +1 -1
  149. package/dist/lib/docs-metadata-sync.js +41 -2
  150. package/dist/lib/durable-job.d.ts +8 -0
  151. package/dist/lib/durable-job.d.ts.map +1 -1
  152. package/dist/lib/durable-job.js +10 -0
  153. package/dist/lib/http/client.d.ts +9 -8
  154. package/dist/lib/http/client.d.ts.map +1 -1
  155. package/dist/lib/http/client.js +44 -2
  156. package/dist/lib/instructions/templates.js +4 -4
  157. package/package.json +2 -2
  158. package/src/commander.ts +13 -0
  159. package/src/commands/admission.ts +272 -29
  160. package/src/commands/agents.ts +132 -27
  161. package/src/commands/browse.ts +208 -6
  162. package/src/commands/fetch.ts +1 -0
  163. package/src/commands/ledger-v3.ts +8 -2
  164. package/src/commands/presence.ts +49 -0
  165. package/src/commands/qa-run.ts +4 -3
  166. package/src/commands/review-pack.ts +41 -5
  167. package/src/core/agents/index.ts +6 -0
  168. package/src/core/agents/live-authority-v3.ts +11 -4
  169. package/src/core/agents/render/session-context.ts +1 -7
  170. package/src/core/agents/session-events.ts +18 -3
  171. package/src/core/agents/state/heartbeat-reader.ts +3 -0
  172. package/src/core/agents/state/live-coordination-view.ts +13 -6
  173. package/src/core/agents/state/parent-reference-contract.ts +14 -0
  174. package/src/core/agents/state/parent-reference.ts +179 -0
  175. package/src/core/config.ts +85 -0
  176. package/src/core/diagnostics/path-identity.ts +52 -6
  177. package/src/core/events/v3/canonical.ts +46 -13
  178. package/src/core/events/v3/index.ts +3 -0
  179. package/src/core/events/v3/producers/recorder.ts +151 -13
  180. package/src/core/events/v3/reader.ts +55 -11
  181. package/src/core/events/v3/validate.ts +42 -1
  182. package/src/core/hooks/adapter/native-parent.ts +109 -0
  183. package/src/core/hooks/cli.ts +83 -4
  184. package/src/core/hooks/resolve/owner.ts +0 -23
  185. package/src/core/hooks/shell-admission.ts +634 -0
  186. package/src/core/hooks/shell-commit-tree.ts +102 -0
  187. package/src/core/inbox/contract.ts +18 -0
  188. package/src/core/inbox/peer-messages.ts +501 -15
  189. package/src/core/inbox/service.ts +108 -3
  190. package/src/core/inbox/targets.ts +94 -3
  191. package/src/core/presence/git.ts +45 -37
  192. package/src/core/presence/index.ts +16 -8
  193. package/src/core/presence/mail.ts +620 -0
  194. package/src/core/storage/modes.ts +6 -0
  195. package/src/core/storage/segments.ts +5 -4
  196. package/src/lib/admission-history.ts +267 -0
  197. package/src/lib/admission.ts +217 -19
  198. package/src/lib/browser/client.ts +147 -35
  199. package/src/lib/browser/content-checks.ts +14 -3
  200. package/src/lib/browser/critique.ts +113 -3
  201. package/src/lib/browser/geometry.ts +63 -14
  202. package/src/lib/browser/index.ts +5 -0
  203. package/src/lib/browser/page-review-contracts.ts +6 -1
  204. package/src/lib/browser/page-review-judge.ts +58 -13
  205. package/src/lib/browser/page-review-pack.ts +13 -2
  206. package/src/lib/browser/qa-run-contracts.ts +30 -4
  207. package/src/lib/browser/qa-run.ts +78 -17
  208. package/src/lib/browser/runts.ts +85 -37
  209. package/src/lib/browser/windows-chrome.ts +50 -0
  210. package/src/lib/browser/windows-login-sync.ts +275 -0
  211. package/src/lib/cookies/client.ts +62 -10
  212. package/src/lib/cookies/index.ts +3 -0
  213. package/src/lib/docs-metadata-sync.ts +44 -2
  214. package/src/lib/durable-job.ts +15 -0
  215. package/src/lib/http/client.ts +63 -1
  216. package/src/lib/instructions/templates.ts +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../../src/commands/presence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA2BnD;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA8KjF"}
1
+ {"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../../src/commands/presence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA6BnD;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA6NjF"}
@@ -1,7 +1,9 @@
1
1
  import { monorepoRoot } from "../core/agents/coord-client.js";
2
2
  import { emitEventV3, nativeSessionIdentity, normalizeAdapter, resolveOwner, } from "../core/agents/index.js";
3
3
  import { readLiveCoordinationRow } from "../core/agents/state/live-coordination-view.js";
4
+ import { peerInbox } from "../core/inbox/peer-messages.js";
4
5
  import { fetchPresence, publishPresence, readRemoteMachines, relayDaemonStatus, runRelayDaemon, } from "../core/presence/index.js";
6
+ import { importMail, mailStatus, publishMail } from "../core/presence/mail.js";
5
7
  import { ageSeconds, applyDetection, clearPresence, formatAge, presenceFilePath, readPresence, writePresence, } from "../lib/presence.js";
6
8
  /**
7
9
  * `presence`: two related surfaces under one name.
@@ -98,6 +100,44 @@ export function registerPresenceCommand(program, emit) {
98
100
  }
99
101
  emit.data(r);
100
102
  });
103
+ cmd
104
+ .command("mail")
105
+ .description("Show cross-machine peer messages (ADR 0222): this machine's unacknowledged outbox, " +
106
+ "acknowledgements it is publishing, and delivered/expired counts. --sync fetches, " +
107
+ "imports, and publishes first (synchronous; errors report).")
108
+ .option("--sync", "Fetch peers' refs, import mail addressed here, and publish this machine's ref")
109
+ .option("--json", "JSON output")
110
+ .action((opts) => {
111
+ const root = requireRoot(emit);
112
+ let sync;
113
+ if (opts.sync) {
114
+ const fetched = fetchPresence(root, { force: true, sync: true });
115
+ if (fetched.status === "error") {
116
+ emit.error({ code: "fetch_failed", message: fetched.error });
117
+ process.exit(1);
118
+ }
119
+ const imported = importMail(root, peerInbox(root), { publish: false });
120
+ const published = publishMail(root, { sync: true });
121
+ if (published.status === "error") {
122
+ emit.error({ code: "publish_failed", message: published.error });
123
+ process.exit(1);
124
+ }
125
+ sync = { imported, published };
126
+ }
127
+ const status = mailStatus(root);
128
+ if (opts.json)
129
+ emit.config({ format: "json" });
130
+ if (opts.json || !process.stdout.isTTY) {
131
+ emit.data({ ...status, ...(sync ? { sync } : {}) });
132
+ return;
133
+ }
134
+ emit.text(`${status.machine}: ${status.outbox.length} waiting for acknowledgement, ` +
135
+ `${status.acks} acknowledgements published, ${status.delivered} delivered, ` +
136
+ `${status.expired} expired\n`);
137
+ for (const m of status.outbox) {
138
+ emit.text(` ${m.message_id} to agent-${m.recipient} on ${m.to_machine} (queued ${m.queued_at})\n`);
139
+ }
140
+ });
101
141
  cmd
102
142
  .command("relay-daemon")
103
143
  .description("Run the relay client daemon in the foreground (normally spawned detached by the hooks " +
@@ -1 +1 @@
1
- {"version":3,"file":"qa-run.d.ts","sourceRoot":"","sources":["../../src/commands/qa-run.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA8B1E,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAElD,sDAAsD;AACtD,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAqB/C,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CAodN"}
1
+ {"version":3,"file":"qa-run.d.ts","sourceRoot":"","sources":["../../src/commands/qa-run.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA+B1E,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAElD,sDAAsD;AACtD,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAqB/C,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CAodN"}
@@ -11,6 +11,7 @@ import { artifactsRoot } from "../core/artifacts/index.js";
11
11
  import { resolveBinName, reviewPackAutoCleanEnabled } from "../core/config.js";
12
12
  import { createManagedQaOutParent, managedQaReviewGuidance, resolveQaRepoRoot, } from "../core/qa-artifacts.js";
13
13
  import { acquireAdmission, admissionBaseDir, admissionStatus } from "../lib/admission.js";
14
+ import { PAGE_REVIEW_MAX_TILE_BUDGET } from "../lib/browser/page-review-contracts.js";
14
15
  import { deleteExpiredPacks, PAGE_REVIEW_DEFAULT_RETENTION_MINUTES, } from "../lib/browser/page-review-pack.js";
15
16
  import { QA_RUN_JOB_FILENAME, QA_RUN_RESULT_FILENAME, QA_RUN_STATUS_FILENAME, runQaMatrix, } from "../lib/browser/qa-run.js";
16
17
  import { QA_RUN_JOB_SCHEMA_VERSION, QA_RUN_STATUS_SCHEMA_VERSION, validateQaRunJob, } from "../lib/browser/qa-run-contracts.js";
@@ -35,7 +36,7 @@ export function registerQaRunCommand(program, emit, context) {
35
36
  "always run serially; the judge pool is policy.critique_pool / --pool.")
36
37
  .option("--pool <n>", "Vision calls in flight during the judge stage, across every context (1-16; default: " +
37
38
  "the provider's own concurrency). Sets policy.critique_pool.")
38
- .option("--tile-budget <n>", "Maximum native tiles across the complete review pack (8-400; default 96).")
39
+ .option("--tile-budget <n>", `Maximum native tiles across the complete review pack (8-${PAGE_REVIEW_MAX_TILE_BUDGET}; default 96).`)
39
40
  .option("--accept-dispositions", "Apply fully reviewed prior decisions only to identical findings on identical native tiles.")
40
41
  .option("--allow-metered", "Permit the critique provider's metered-API fallback. Default: subscription-backed " +
41
42
  "headless harnesses only — exhaustion becomes an incomplete blocker, never a metered call.")
@@ -129,10 +130,10 @@ export function registerQaRunCommand(program, emit, context) {
129
130
  const policy = { ...validation.job.policy };
130
131
  if (opts.tileBudget !== undefined) {
131
132
  const n = Number(opts.tileBudget);
132
- if (!Number.isInteger(n) || n < 8 || n > 400) {
133
+ if (!Number.isInteger(n) || n < 8 || n > PAGE_REVIEW_MAX_TILE_BUDGET) {
133
134
  emit.error({
134
135
  code: "qa_run_invalid_tile_budget",
135
- message: "--tile-budget must be an integer between 8 and 400",
136
+ message: `--tile-budget must be an integer between 8 and ${PAGE_REVIEW_MAX_TILE_BUDGET}`,
136
137
  });
137
138
  process.exitCode = 1;
138
139
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"review-pack.d.ts","sourceRoot":"","sources":["../../src/commands/review-pack.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAkV1E,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CAugCN"}
1
+ {"version":3,"file":"review-pack.d.ts","sourceRoot":"","sources":["../../src/commands/review-pack.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAmV1E,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CA0iCN"}
@@ -11,7 +11,8 @@ import { readLiveCoordinationRow } from "../core/agents/state/live-coordination-
11
11
  import { artifactsRoot } from "../core/artifacts/index.js";
12
12
  import { resolveBinName, reviewPackAutoCleanEnabled } from "../core/config.js";
13
13
  import { createManagedQaOutParent, resolveQaRepoRoot } from "../core/qa-artifacts.js";
14
- import { DEFAULT_CRITIQUE_RUBRIC } from "../lib/browser/critique.js";
14
+ import { DEFAULT_CRITIQUE_RUBRIC, formatCritiqueUsage } from "../lib/browser/critique.js";
15
+ import { PAGE_REVIEW_MAX_TILE_BUDGET } from "../lib/browser/page-review-contracts.js";
15
16
  import { persistPackReviewDecisions } from "../lib/browser/page-review-evidence.js";
16
17
  import { judgePageReviewPack, toCritiqueRecords } from "../lib/browser/page-review-judge.js";
17
18
  import { aggregateMachineOutcome, deleteExpiredPacks, expandedTileFilename, finalizePageReviewPack, findPackTile, findPageReviewPacks, isPackDeletable, listPackContexts, machineFindingTargets, PAGE_REVIEW_DEFAULT_RETENTION_MINUTES, PAGE_REVIEW_DISPOSITIONS, PAGE_REVIEW_FINDING_CATEGORIES, PAGE_REVIEW_FINDING_SEVERITIES, PAGE_REVIEW_SUBAGENT_MODELS, PAGE_REVIEW_VERDICT_SCHEMA, packPaths, readPackContext, readPackFindings, readPackInspectionPlan, readPackManifest, readPackVerdict, resolvePackVerdict, validateFindingsDocument, writePackFindings, } from "../lib/browser/page-review-pack.js";
@@ -205,7 +206,9 @@ export function registerReviewPackCommand(program, emit, context) {
205
206
  .option("--context <spec>", "Rendering context <viewport>[:<theme>[:<state>]] (repeatable; default desktop and " +
206
207
  "mobile in light and dark).", (value, previous = []) => [...previous, value], [])
207
208
  .option("--scope <selector>", "Also tile one screenshot per element matching <selector> (repeatable).", (value, previous = []) => [...previous, value], [])
208
- .option("--max-tiles <n>", "Native tile cap per context, including required top and bottom bands.")
209
+ .option("--max-tiles <n>", "Native tile cap per context, including required top and bottom bands (default 24). " +
210
+ `The whole pack never exceeds ${PAGE_REVIEW_MAX_TILE_BUDGET} tiles, so the cap is ` +
211
+ "lowered when the contexts would need more.")
209
212
  .option("--concurrency <n>", "Concurrent capture browsers (1-8; default 2).", "2")
210
213
  .option("--timeout <ms>", "Per-capture timeout in milliseconds (default 120000).", "120000")
211
214
  .option("--retain <minutes>", `Minutes the pack lives before the whole directory is deleted (1-43200; default ` +
@@ -231,6 +234,23 @@ export function registerReviewPackCommand(program, emit, context) {
231
234
  process.exitCode = 1;
232
235
  return;
233
236
  }
237
+ const requestedMaxTiles = Number(opts.maxTiles ?? "24");
238
+ if (!Number.isInteger(requestedMaxTiles) ||
239
+ requestedMaxTiles < 1 ||
240
+ requestedMaxTiles > PAGE_REVIEW_MAX_TILE_BUDGET) {
241
+ emit.error({
242
+ code: "review_pack_invalid_max_tiles",
243
+ message: `--max-tiles must be an integer between 1 and ${PAGE_REVIEW_MAX_TILE_BUDGET}`,
244
+ });
245
+ process.exitCode = 1;
246
+ return;
247
+ }
248
+ // The judge refuses a pack above the ceiling, so share it across contexts here.
249
+ const perContextMaxTiles = Math.max(2, Math.min(requestedMaxTiles, Math.floor(PAGE_REVIEW_MAX_TILE_BUDGET / contexts.length)));
250
+ if (perContextMaxTiles < requestedMaxTiles) {
251
+ emit.log(`review-pack: ${contexts.length} contexts share the ${PAGE_REVIEW_MAX_TILE_BUDGET}-tile ceiling; ` +
252
+ `capping each at ${perContextMaxTiles} tiles`, "warn");
253
+ }
234
254
  const concurrency = Math.max(1, Math.min(8, Number.parseInt(opts.concurrency ?? "2", 10) || 2));
235
255
  const timeoutMs = Math.max(1000, Number.parseInt(opts.timeout ?? "120000", 10) || 120_000);
236
256
  const repoRoot = resolveQaRepoRoot(context);
@@ -291,7 +311,8 @@ export function registerReviewPackCommand(program, emit, context) {
291
311
  "--qa-state",
292
312
  ctx.state,
293
313
  ...(opts.scope ?? []).flatMap((selector) => ["--review-pack-scope", selector]),
294
- ...(opts.maxTiles !== undefined ? ["--check-critique-max-tiles", opts.maxTiles] : []),
314
+ "--check-critique-max-tiles",
315
+ String(perContextMaxTiles),
295
316
  ];
296
317
  emit.log(`capture ${ctx.id}`, "info");
297
318
  const res = await defaultQaRunExec(argv, { timeoutMs, env });
@@ -434,8 +455,12 @@ export function registerReviewPackCommand(program, emit, context) {
434
455
  else
435
456
  process.env[QA_RUN_HEADLESS_ONLY_ENV] = prior;
436
457
  const merged = new Map((manifest.critique ?? []).map((row) => [row.context_id, row]));
437
- for (const row of toCritiqueRecords(result))
438
- merged.set(row.context_id, row);
458
+ for (const row of toCritiqueRecords(result)) {
459
+ // Re-judging never changes the captured coverage, so a signoff's
460
+ // sampled acceptance (ADR 0224) still applies.
461
+ const prior = merged.get(row.context_id)?.coverage_mode;
462
+ merged.set(row.context_id, prior ? { ...row, coverage_mode: prior } : row);
463
+ }
439
464
  const judgedRecords = new Map(result.contexts.map((row) => [row.context_id, row.record]));
440
465
  finalizePageReviewPack({
441
466
  packDir,
@@ -461,7 +486,9 @@ export function registerReviewPackCommand(program, emit, context) {
461
486
  ` · ${high} high / ${row.findings.length - high} other finding(s)` +
462
487
  (row.error ? ` · ${row.error}` : ""), row.outcome === "pass" ? "info" : "warn");
463
488
  }
464
- emit.log(`judge: ${result.outcome} · pool ${result.pool.concurrency} · ${result.tiles_reviewed} tile(s) in ${result.pool.wall_time_ms}ms · ${packPaths(packDir).review}`, result.outcome === "pass" ? "info" : "warn");
489
+ emit.log(`judge: ${result.outcome} · pool ${result.pool.concurrency} · ${result.tiles_reviewed} tile(s) in ${result.pool.wall_time_ms}ms` +
490
+ (result.usage ? ` · ${formatCritiqueUsage(result.usage)}` : "") +
491
+ ` · ${packPaths(packDir).review}`, result.outcome === "pass" ? "info" : "warn");
465
492
  if (opts.json)
466
493
  emit.data(result);
467
494
  if (result.outcome === "fail")
@@ -10,5 +10,6 @@ export * from "./canonical-emit.js";
10
10
  export * from "./coord-client.js";
11
11
  export * from "./live-observation-v3.js";
12
12
  export * from "./session-events.js";
13
+ export { type AgentParentReference, type AgentParentReferenceOptions, type AgentParentSubject, resolveAgentParentReference, } from "./state/parent-reference.js";
13
14
  export * from "./state/session-state.js";
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/agents/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/agents/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,KAAK,kBAAkB,EACvB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AACrC,cAAc,0BAA0B,CAAC"}
@@ -10,4 +10,5 @@ export * from "./canonical-emit.js";
10
10
  export * from "./coord-client.js";
11
11
  export * from "./live-observation-v3.js";
12
12
  export * from "./session-events.js";
13
+ export { resolveAgentParentReference, } from "./state/parent-reference.js";
13
14
  export * from "./state/session-state.js";
@@ -1 +1 @@
1
- {"version":3,"file":"live-authority-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/live-authority-v3.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"live-authority-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/live-authority-v3.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ import { readCoordinationViewV3, requireAuthoritySafeCoordinationViewV3, } from
6
6
  import { fingerprintContextV3 } from "../events/v3/fingerprint-keys.js";
7
7
  import { LIVE_HOOK_V3_PRODUCER_ID, liveInstanceIdV3, livePlatformV3, resolveLiveEventLedgerRouteV3, } from "../events/v3/live-routing.js";
8
8
  import { recordCoordinationAuthorityV3, } from "../events/v3/producers/coordination-recorder.js";
9
- import { listHookProducerStateRecordsV3, readHookProducerStateV3, readTerminalHookProducerStateV3, recordHookSignalV3, } from "../events/v3/producers/recorder.js";
9
+ import { readHookProducerStateV3, readTerminalHookProducerStateV3, recordHookSignalV3, scanHookProducerStateRecordsV3, } from "../events/v3/producers/recorder.js";
10
10
  import { canonicalClaimPath } from "./claim-path.js";
11
11
  import { acquireClaim, readHeartbeat, releaseClaim, setIdentityCache, setLifecycleCache, setTask, } from "./state/heartbeat-writer.js";
12
12
  import { liveCoordinationAdapterV3, readLiveCoordinationRow, } from "./state/live-coordination-view.js";
@@ -139,14 +139,21 @@ function readSessionProducerStatesForBootstrap(coordRoot, nativeSessionId) {
139
139
  }
140
140
  }
141
141
  function readInstanceProducerStatesForBootstrap(coordRoot, instanceId) {
142
+ let scan;
142
143
  try {
143
- return listHookProducerStateRecordsV3(coordRoot, { includeTerminal: true })
144
- .map((record) => record.state)
145
- .filter((state) => state.instance_id === instanceId);
144
+ scan = scanHookProducerStateRecordsV3(coordRoot, { includeTerminal: true });
146
145
  }
147
146
  catch {
148
147
  throw new LiveCoordinationAuthorityV3Error("producer_state_unsafe");
149
148
  }
149
+ // Another session's invalid file does not block this one; this instance's
150
+ // own invalid file still fails closed.
151
+ if (scan.invalid.some((file) => file.instance_id === instanceId)) {
152
+ throw new LiveCoordinationAuthorityV3Error("producer_state_unsafe");
153
+ }
154
+ return scan.records
155
+ .map((record) => record.state)
156
+ .filter((state) => state.instance_id === instanceId);
150
157
  }
151
158
  function terminalGenerationForSession(view, instanceId, sessionId) {
152
159
  return Object.values(view.terminal_generations).some((generation) => generation.instance_id === instanceId && generation.session_id === sessionId);
@@ -6,7 +6,6 @@
6
6
  * Outputs a Claude Code SessionStart hookSpecificOutput.additionalContext
7
7
  * string.
8
8
  */
9
- import { statSync } from "node:fs";
10
9
  export interface RenderOpts {
11
10
  coordRoot: string;
12
11
  instanceId: string;
@@ -43,9 +42,4 @@ export declare function checkWiring(coordRoot: string): string[];
43
42
  * (or "" when no councils await input).
44
43
  */
45
44
  export declare function formatPendingCouncils(coordRoot: string, agentName: string): string;
46
- /**
47
- * Suppress unused import warning when statSync isn't used in this file
48
- * (kept exported for future renderers, e.g. heartbeat-freshness coloring).
49
- */
50
- export declare const _ensureStatSyncImported: typeof statSync;
51
45
  //# sourceMappingURL=session-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-context.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/render/session-context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAyC,QAAQ,EAAE,MAAM,SAAS,CAAC;AAyB1E,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;+BAC2B;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;CAC3D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CA8F7D;AA6LD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBvD;AA0DD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAiDlF;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,iBAAW,CAAC"}
1
+ {"version":3,"file":"session-context.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/render/session-context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4BH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;+BAC2B;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;CAC3D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CA8F7D;AA6LD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBvD;AA0DD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAiDlF"}
@@ -7,7 +7,7 @@
7
7
  * string.
8
8
  */
9
9
  import { spawnSync } from "node:child_process";
10
- import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
10
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
11
11
  import { join } from "node:path";
12
12
  import { resolveBinName, resolveHooksSetupHint } from "../../config.js";
13
13
  import { harneryVersion, loadAdapterWiring } from "../../hooks/adapter/wiring.js";
@@ -389,8 +389,3 @@ export function formatPendingCouncils(coordRoot, agentName) {
389
389
  }
390
390
  return `Councils waiting on your input (${pending.length} open): ${list}. Run \`${bin} agents council list --mine\` to see all of them, then \`${bin} agents council show <id>\` for any brief.`;
391
391
  }
392
- /**
393
- * Suppress unused import warning when statSync isn't used in this file
394
- * (kept exported for future renderers, e.g. heartbeat-freshness coloring).
395
- */
396
- export const _ensureStatSyncImported = statSync;
@@ -1 +1 @@
1
- {"version":3,"file":"session-events.d.ts","sourceRoot":"","sources":["../../../src/core/agents/session-events.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH,mDAAmD;AACnD,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,GAAG,yBAAyB,GAAG,mBAAmB,CAAC;AAEnG;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAG7C;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBjE;AA4GD,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrD;AAgED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,gBAAgB,EACtB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,IAAI,CAkDN;AAED,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,SAAO,GAAG,MAAM,CAGxD"}
1
+ {"version":3,"file":"session-events.d.ts","sourceRoot":"","sources":["../../../src/core/agents/session-events.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH,mDAAmD;AACnD,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,GAAG,yBAAyB,GAAG,mBAAmB,CAAC;AAEnG;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAG7C;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBjE;AAyHD,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrD;AAgED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,gBAAgB,EACtB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,IAAI,CAoDN;AAED,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,SAAO,GAAG,MAAM,CAGxD"}
@@ -62,16 +62,21 @@ function commandKey(fields) {
62
62
  ? JSON.stringify([fields.instance_id, fields.cmd_id])
63
63
  : undefined;
64
64
  }
65
- function flushCommandOutput(command) {
65
+ /**
66
+ * `deferDrain` stages each summary durably in the spool without appending it,
67
+ * for a caller that writes the completion next: that write drains every staged
68
+ * row under one lease and one witness advance instead of one per row.
69
+ */
70
+ function flushCommandOutput(command, deferDrain = false) {
66
71
  for (const summary of command.streams.values()) {
67
- recordCommandObservation("command.output_observed", command.fields, command.coordRoot, summary);
72
+ recordCommandObservation("command.output_observed", command.fields, command.coordRoot, summary, deferDrain);
68
73
  }
69
74
  command.streams.clear();
70
75
  }
71
76
  /** Emit a command/narration event to the canonical stream. Swallows every
72
77
  * error and skips when identity can't be resolved: telemetry must never break
73
78
  * or slow down a command. */
74
- function recordCommandObservation(type, fields, coordRoot, summary) {
79
+ function recordCommandObservation(type, fields, coordRoot, summary, deferDrain = false) {
75
80
  const instanceId = typeof fields.instance_id === "string" ? fields.instance_id : undefined;
76
81
  if (!instanceId)
77
82
  return false;
@@ -104,6 +109,7 @@ function recordCommandObservation(type, fields, coordRoot, summary) {
104
109
  platform: livePlatformV3(),
105
110
  ...(fields.bridge === "codex-wsl" ? { bridge: "codex-wsl" } : {}),
106
111
  monotonic_ns: process.hrtime.bigint().toString(),
112
+ ...(deferDrain ? { writerOptions: { deferDrain: true } } : {}),
107
113
  });
108
114
  if (result.state === "generation_unavailable") {
109
115
  const expectedLifecycleReopenGap = result.reason === "turn_not_started" &&
@@ -243,8 +249,10 @@ export function writeSessionEvent(type, fields = {}) {
243
249
  const coordRoot = command?.coordRoot ?? coordinationRootPath();
244
250
  if (type === "command.completed") {
245
251
  pendingCommands.delete(key);
252
+ // The completion below drains the staged summaries with itself. If it
253
+ // never writes, the rows stay durable in the spool for the next drain.
246
254
  if (command)
247
- flushCommandOutput(command);
255
+ flushCommandOutput(command, true);
248
256
  recordCommandObservation(type, fields, coordRoot);
249
257
  }
250
258
  else if (recordCommandObservation(type, fields, coordRoot) && !command) {
@@ -1,4 +1,5 @@
1
1
  /** Read-only access to the generation-bound heartbeat cache. */
2
+ import type { AgentParentReference } from "./parent-reference-contract.js";
2
3
  import type { AgentActivity, TaskState } from "./session-state.js";
3
4
  export interface Heartbeat {
4
5
  schema_version?: number;
@@ -46,6 +47,8 @@ export interface Heartbeat {
46
47
  last_status_at?: string;
47
48
  current_turn_id?: string;
48
49
  parent_instance_id?: string;
50
+ /** Read-only display/recipient evidence; never a claim or lifecycle authority input. */
51
+ parent_reference?: AgentParentReference;
49
52
  workflow_run_id?: string;
50
53
  workflow_agent_id?: string;
51
54
  /** Disposable-cache bindings that prove a row belongs to the current V3 generation. */
@@ -1 +1 @@
1
- {"version":3,"file":"heartbeat-reader.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/heartbeat-reader.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAIhE,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEnE,MAAM,WAAW,SAAS;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wEAAwE;IACxE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,kCAAkC,CAAC,EAAE,MAAM,CAAC;IAC5C;;;;;OAKG;IACH,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uFAAuF;IACvF,cAAc,CAAC,EAAE,QAAQ,MAAM,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,MAAM,EAAE,CAAC;IACnC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,aAAa,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAClC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAU3E;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAQrF"}
1
+ {"version":3,"file":"heartbeat-reader.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/heartbeat-reader.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAIhE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEnE,MAAM,WAAW,SAAS;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wEAAwE;IACxE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,kCAAkC,CAAC,EAAE,MAAM,CAAC;IAC5C;;;;;OAKG;IACH,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uFAAuF;IACvF,cAAc,CAAC,EAAE,QAAQ,MAAM,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,MAAM,EAAE,CAAC;IACnC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,aAAa,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAClC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAU3E;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAQrF"}
@@ -1,5 +1,5 @@
1
1
  import { type EventAdapterIdV3 } from "../../events/v3/adapter-id.js";
2
- import { type CoordinationGenerationViewV3 } from "../../events/v3/coordination-view.js";
2
+ import { type CoordinationGenerationViewV3, type CoordinationViewV3 } from "../../events/v3/coordination-view.js";
3
3
  import { type Heartbeat } from "./heartbeat-reader.js";
4
4
  /**
5
5
  * Heartbeat files are disposable V3 caches. These bindings prevent a stale
@@ -12,6 +12,8 @@ export interface V3HeartbeatMaterialization extends Heartbeat {
12
12
  v3_projection_event_id: string;
13
13
  v3_task_state: "set" | "cleared";
14
14
  }
15
+ /** Index exact generations; a current replacement never erases its terminal predecessor. */
16
+ export declare function indexCoordinationGenerationsV3(view: CoordinationViewV3): ReadonlyMap<string, CoordinationGenerationViewV3>;
15
17
  /** Read the live coordination rows through the hard-cut ledger route. */
16
18
  export declare function readLiveCoordinationRows(coordRoot: string): V3HeartbeatMaterialization[];
17
19
  /** Read one current row from the authority-safe V3 projection. */
@@ -1 +1 @@
1
- {"version":3,"file":"live-coordination-view.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-view.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EACL,KAAK,4BAA4B,EAIlC,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAGtE;;;GAGG;AACH,MAAM,WAAW,0BAA2B,SAAQ,SAAS;IAC3D,cAAc,EAAE,CAAC,CAAC;IAClB,cAAc,EAAE,QAAQ,MAAM,EAAE,CAAC;IACjC,gBAAgB,EAAE,OAAO,MAAM,EAAE,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,aAAa,EAAE,KAAK,GAAG,SAAS,CAAC;CAClC;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,EAAE,CA2BxF;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,0BAA0B,GAAG,IAAI,CAuBnC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,gBAAgB,GAAG,IAAI,CAWzB;AA8BD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACnC,UAAU,EAAE,4BAA4B,GACvC,KAAK,IAAI,SAAS,CAMpB;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,4BAA4B,EACxC,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,MAAM,CAAC,EAAE,4BAA4B,GACpC,0BAA0B,CAuD5B;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,4BAA4B,GAAG,MAAM,GAAG,SAAS,CAG9F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,gBAAgB,CAEhF;AAWD,sEAAsE;AACtE,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,YAAY,GAAG,QAAQ,CAAC;IAC/B,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACpD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,oBAAoB,GAAG,IAAI,CA2B7B;AAED,+EAA+E;AAC/E,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAiBhF;AAED,gFAAgF;AAChF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKhE"}
1
+ {"version":3,"file":"live-coordination-view.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-view.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,kBAAkB,EAGxB,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAGtE;;;GAGG;AACH,MAAM,WAAW,0BAA2B,SAAQ,SAAS;IAC3D,cAAc,EAAE,CAAC,CAAC;IAClB,cAAc,EAAE,QAAQ,MAAM,EAAE,CAAC;IACjC,gBAAgB,EAAE,OAAO,MAAM,EAAE,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,aAAa,EAAE,KAAK,GAAG,SAAS,CAAC;CAClC;AAED,4FAA4F;AAC5F,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,kBAAkB,GACvB,WAAW,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAMnD;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,EAAE,CAyBxF;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,0BAA0B,GAAG,IAAI,CAqBnC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,gBAAgB,GAAG,IAAI,CAWzB;AA8BD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACnC,UAAU,EAAE,4BAA4B,GACvC,KAAK,IAAI,SAAS,CAMpB;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,4BAA4B,EACxC,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,MAAM,CAAC,EAAE,4BAA4B,GACpC,0BAA0B,CAuD5B;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,4BAA4B,GAAG,MAAM,GAAG,SAAS,CAG9F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,gBAAgB,CAEhF;AAWD,sEAAsE;AACtE,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,YAAY,GAAG,QAAQ,CAAC;IAC/B,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACpD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,oBAAoB,GAAG,IAAI,CA2B7B;AAED,+EAA+E;AAC/E,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAiBhF;AAED,gFAAgF;AAChF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKhE"}
@@ -5,6 +5,10 @@ import { readCoordinationViewV3, requireAuthoritySafeCoordinationViewV3, } from
5
5
  import { liveInstanceIdV3, nativeInstanceIdV3, observeLiveEventLedgerRouteV3, } from "../../events/v3/live-route-observer.js";
6
6
  import { readHeartbeat } from "./heartbeat-reader.js";
7
7
  import { resolveName } from "./names.js";
8
+ /** Index exact generations; a current replacement never erases its terminal predecessor. */
9
+ export function indexCoordinationGenerationsV3(view) {
10
+ return new Map([...Object.values(view.terminal_generations), ...Object.values(view.instances)].map((generation) => [generation.generation_id, generation]));
11
+ }
8
12
  /** Read the live coordination rows through the hard-cut ledger route. */
9
13
  export function readLiveCoordinationRows(coordRoot) {
10
14
  const route = observeLiveEventLedgerRouteV3(coordRoot);
@@ -18,7 +22,7 @@ export function readLiveCoordinationRows(coordRoot) {
18
22
  return [];
19
23
  }
20
24
  const caches = readV3Caches(coordRoot);
21
- const byGeneration = new Map(Object.values(view.instances).map((generation) => [generation.generation_id, generation]));
25
+ const byGeneration = indexCoordinationGenerationsV3(view);
22
26
  return Object.values(view.instances)
23
27
  .filter((generation) => generation.authority_eligible)
24
28
  .map((generation) => {
@@ -40,7 +44,7 @@ export function readLiveCoordinationRow(coordRoot, nativeInstanceId) {
40
44
  return null;
41
45
  const cache = readHeartbeat(coordRoot, nativeInstanceId);
42
46
  const parent = generation.parent_generation_id
43
- ? Object.values(view.instances).find((candidate) => candidate.generation_id === generation.parent_generation_id)
47
+ ? indexCoordinationGenerationsV3(view).get(generation.parent_generation_id)
44
48
  : undefined;
45
49
  return projectHeartbeatV3(coordRoot, generation, isCurrentV3HeartbeatCache(cache, generation) ? cache : undefined, nativeInstanceId, parent);
46
50
  }
@@ -0,0 +1,16 @@
1
+ export type AgentParentReference = {
2
+ state: "verified";
3
+ relationship: "delegated-child" | "native-child";
4
+ parent_instance_id: string;
5
+ parent_v3_instance_id: string;
6
+ parent_generation_id: string | null;
7
+ parent_session_id: string | null;
8
+ parent_name: string | null;
9
+ source: "v3-session-link" | "native-session-metadata";
10
+ source_witness?: string;
11
+ addressable: boolean;
12
+ } | {
13
+ state: "none" | "unknown" | "conflict";
14
+ reason: string;
15
+ };
16
+ //# sourceMappingURL=parent-reference-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parent-reference-contract.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/parent-reference-contract.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC5B;IACE,KAAK,EAAE,UAAU,CAAC;IAClB,YAAY,EAAE,iBAAiB,GAAG,cAAc,CAAC;IACjD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,iBAAiB,GAAG,yBAAyB,CAAC;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;CACtB,GACD;IAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { CoordinationViewV3 } from "../../events/v3/coordination-view.js";
2
+ import { type NativeParentObservation, type NativeParentRequest } from "../../hooks/adapter/native-parent.js";
3
+ import type { AgentParentReference } from "./parent-reference-contract.js";
4
+ export type { AgentParentReference } from "./parent-reference-contract.js";
5
+ export interface AgentParentSubject {
6
+ instance_id: string;
7
+ generation_id?: string;
8
+ v3_generation_id?: string;
9
+ platform?: string;
10
+ native_session_id?: string;
11
+ }
12
+ export interface AgentParentReferenceOptions {
13
+ view?: CoordinationViewV3;
14
+ readNativeParent?: (request: NativeParentRequest) => NativeParentObservation;
15
+ }
16
+ /** Display/recipient evidence only. Never use native evidence as a claim or lifecycle waiver. */
17
+ export declare function resolveAgentParentReference(coordRoot: string, child: AgentParentSubject, options?: AgentParentReferenceOptions): AgentParentReference;
18
+ //# sourceMappingURL=parent-reference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parent-reference.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/parent-reference.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,kBAAkB,EACnB,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EAEzB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,YAAY,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,uBAAuB,CAAC;CAC9E;AAED,iGAAiG;AACjG,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,kBAAkB,EACzB,OAAO,GAAE,2BAAgC,GACxC,oBAAoB,CAyEtB"}
@@ -0,0 +1,119 @@
1
+ import { readCoordinationViewV3 } from "../../events/v3/coordination-view.js";
2
+ import { liveInstanceIdV3, nativeInstanceIdV3 } from "../../events/v3/live-route-observer.js";
3
+ import { readNativeParentReference, } from "../../hooks/adapter/native-parent.js";
4
+ import { resolveName } from "./names.js";
5
+ /** Display/recipient evidence only. Never use native evidence as a claim or lifecycle waiver. */
6
+ export function resolveAgentParentReference(coordRoot, child, options = {}) {
7
+ try {
8
+ const view = options.view ?? readCoordinationViewV3(coordRoot);
9
+ if (!view.source_complete || !view.authority_safe)
10
+ return unknown("parent_authority_unsafe");
11
+ if (child.generation_id &&
12
+ child.v3_generation_id &&
13
+ child.generation_id !== child.v3_generation_id) {
14
+ return unknown("child_generation_mismatch");
15
+ }
16
+ const instance = liveInstanceIdV3(child.instance_id);
17
+ const generationId = child.generation_id ?? child.v3_generation_id;
18
+ const generations = [
19
+ ...Object.values(view.instances),
20
+ ...Object.values(view.terminal_generations),
21
+ ];
22
+ const generation = generationId
23
+ ? generations.find((row) => row.generation_id === generationId && row.instance_id === instance)
24
+ : view.instances[instance];
25
+ if (!generation)
26
+ return unknown("child_generation_unavailable");
27
+ if (!safe(view, generation))
28
+ return unknown("child_authority_unsafe");
29
+ const canonical = generation.parent_generation_id
30
+ ? generations.find((row) => row.generation_id === generation.parent_generation_id)
31
+ : undefined;
32
+ if (generation.parent_generation_id && !canonical)
33
+ return unknown("parent_generation_unavailable");
34
+ if (canonical && cyclic(generations, generation)) {
35
+ return { state: "conflict", reason: "parent_lineage_cycle" };
36
+ }
37
+ const adapter = generation.runtime_attestation.adapter;
38
+ const platform = adapter.state === "observed" ? adapter.value.id : child.platform;
39
+ const nativeId = child.native_session_id ?? nativeInstanceIdV3(instance);
40
+ const native = platform === "codex" && liveInstanceIdV3(nativeId) === instance
41
+ ? (options.readNativeParent ?? readNativeParentReference)({
42
+ adapter: platform,
43
+ native_session_id: nativeId,
44
+ })
45
+ : { state: "unknown", reason: "native_child_identity_unavailable" };
46
+ if (canonical) {
47
+ if (native.state === "none" ||
48
+ (native.state === "observed" &&
49
+ liveInstanceIdV3(native.parent_session_id) !== canonical.instance_id)) {
50
+ return { state: "conflict", reason: "parent_sources_disagree" };
51
+ }
52
+ return reference(coordRoot, view, canonical.instance_id, canonical, "v3-session-link");
53
+ }
54
+ if (native.state === "observed") {
55
+ const parentInstance = liveInstanceIdV3(native.parent_session_id);
56
+ if (parentInstance === instance)
57
+ return { state: "conflict", reason: "parent_self_reference" };
58
+ const parent = recipientGeneration(view, parentInstance);
59
+ if (parent && cyclic(generations, generation, parent)) {
60
+ return { state: "conflict", reason: "parent_lineage_cycle" };
61
+ }
62
+ return reference(coordRoot, view, parentInstance, parent, "native-session-metadata", native.source_witness);
63
+ }
64
+ return { state: native.state, reason: native.reason };
65
+ }
66
+ catch {
67
+ return unknown("parent_reference_unavailable");
68
+ }
69
+ }
70
+ function reference(root, view, instance, parent, source, witness) {
71
+ const native = nativeInstanceIdV3(instance);
72
+ const name = resolveName(root, native)?.name ?? null;
73
+ const recipient = recipientGeneration(view, instance);
74
+ return {
75
+ state: "verified",
76
+ relationship: source === "v3-session-link" ? "delegated-child" : "native-child",
77
+ parent_instance_id: native,
78
+ parent_v3_instance_id: instance,
79
+ parent_generation_id: parent?.generation_id ?? null,
80
+ parent_session_id: parent?.session_id ?? null,
81
+ parent_name: name,
82
+ source,
83
+ ...(witness ? { source_witness: witness } : {}),
84
+ addressable: Boolean(parent && recipient?.generation_id === parent.generation_id && safe(view, parent) && name),
85
+ };
86
+ }
87
+ function recipientGeneration(view, instance) {
88
+ return (view.instances[instance] ??
89
+ Object.values(view.terminal_generations)
90
+ .filter((row) => row.instance_id === instance)
91
+ .sort((a, b) => b.source_position.segment_ordinal - a.source_position.segment_ordinal ||
92
+ b.source_position.byte_offset - a.source_position.byte_offset)[0]);
93
+ }
94
+ function safe(view, generation) {
95
+ return !(view.diagnostics_by_generation[generation.generation_id] ?? []).some((d) => d.authority_blocking);
96
+ }
97
+ function cyclic(generations, child, first) {
98
+ const seen = new Set([child.generation_id]);
99
+ let cursor = first ?? child;
100
+ for (let depth = 0; depth <= generations.length; depth++) {
101
+ if (cursor !== child) {
102
+ if (seen.has(cursor.generation_id) || cursor.instance_id === child.instance_id)
103
+ return true;
104
+ seen.add(cursor.generation_id);
105
+ }
106
+ if (!cursor.parent_generation_id)
107
+ return false;
108
+ const next = generations.find((g) => g.generation_id === cursor.parent_generation_id);
109
+ if (!next)
110
+ return false;
111
+ if (seen.has(next.generation_id))
112
+ return true;
113
+ cursor = next;
114
+ }
115
+ return true;
116
+ }
117
+ function unknown(reason) {
118
+ return { state: "unknown", reason };
119
+ }