@oxagen/cli 3.0.0 → 3.0.1-27

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 (3) hide show
  1. package/README.md +7 -7
  2. package/oxagen.mjs +933 -536
  3. package/package.json +2 -2
package/oxagen.mjs CHANGED
@@ -4582,7 +4582,7 @@ function member(kind) {
4582
4582
  function parseTachoEvent(value) {
4583
4583
  return tachoEventSchema.parse(value);
4584
4584
  }
4585
- var TACHO_ENVELOPE_VERSION, digest, str, short, u8, u16, u32, u64, bool, ts, json, TACHO_RUNTIMES, TACHO_FIDELITIES, TACHO_SOURCES, ENFORCEMENT_TIERS, TOOL_STATUSES, POLICY_DECISIONS, POLICY_SOURCES, EFFECT_KINDS, GAP_CAUSES, INCIDENT_KINDS, TOKEN_SOURCE_BASES, SYSTEM_CONTEXT_PART_KINDS, SYSTEM_CONTEXT_PARTS_MAX, systemContextPartSchema, toolFacts, modelFacts, TOKEN_SOURCE_COUNTS, promptFacts, policyFacts, subagentFacts, SUBAGENT_CHAINLESS_ATTR, healthFacts, lifecycleFacts, integrityFacts, MAX_OBSERVED_CHANGES, observedChangeSchema, MAX_SESSION_COMMIT_ITEMS, MAX_COMMIT_FILES, MAX_COMMIT_PARENTS, MAX_COMMIT_SUBJECT, commitName, sessionCommitFileSchema, sessionCommitSchema, observationFacts, inventoryFacts, totalsFacts, allFacts, BODY_MEMBER_NAMES, BODY_FACTS_SHAPE, pick, toolKeys, modelKeys, promptKeys, policyKeys, subagentKeys, healthKeys, lifecycleKeys, integrityKeys, inventoryKeys, totalsKeys, observationKeys, KIND_BODIES, TACHO_KINDS, agentIdentitySchema, subagentIdentitySchema, turnRefSchema, contextSchema, hostSchema, anthropicSchema, ADDRESS_MEMBERS, spanSchema, MAX_CONTENT_REDACTIONS, contentSchema, envelopeBase, members, TOKEN_SOURCE_KINDS, tachoRecordedEventSchema, tachoEventSchema;
4585
+ var TACHO_ENVELOPE_VERSION, digest, str, short, u8, u16, u32, u64, i32, bool, ts, json, TACHO_RUNTIMES, TACHO_FIDELITIES, TACHO_SOURCES, ENFORCEMENT_TIERS, TOOL_STATUSES, POLICY_DECISIONS, POLICY_SOURCES, EFFECT_KINDS, GAP_CAUSES, INCIDENT_KINDS, TOKEN_SOURCE_BASES, SYSTEM_CONTEXT_PART_KINDS, SYSTEM_CONTEXT_PARTS_MAX, systemContextPartSchema, toolFacts, modelFacts, TOKEN_SOURCE_COUNTS, promptFacts, policyFacts, subagentFacts, SUBAGENT_CHAINLESS_ATTR, healthFacts, lifecycleFacts, integrityFacts, MAX_OBSERVED_CHANGES, observedChangeSchema, MAX_SESSION_COMMIT_ITEMS, MAX_COMMIT_FILES, MAX_COMMIT_PARENTS, MAX_COMMIT_SUBJECT, commitName, sessionCommitFileSchema, sessionCommitSchema, observationFacts, inventoryFacts, totalsFacts, allFacts, BODY_MEMBER_NAMES, BODY_FACTS_SHAPE, pick, toolKeys, modelKeys, promptKeys, policyKeys, subagentKeys, healthKeys, lifecycleKeys, integrityKeys, inventoryKeys, totalsKeys, observationKeys, KIND_BODIES, TACHO_KINDS, agentIdentitySchema, subagentIdentitySchema, turnRefSchema, contextSchema, hostSchema, anthropicSchema, ADDRESS_MEMBERS, spanSchema, MAX_CONTENT_REDACTIONS, contentSchema, envelopeBase, members, TOKEN_SOURCE_KINDS, tachoRecordedEventSchema, tachoEventSchema;
4586
4586
  var init_envelope = __esm({
4587
4587
  "../../packages/tacho/src/envelope.ts"() {
4588
4588
  "use strict";
@@ -4597,6 +4597,7 @@ var init_envelope = __esm({
4597
4597
  u16 = external_exports.number().int().min(0).max(65535);
4598
4598
  u32 = external_exports.number().int().min(0).max(4294967295);
4599
4599
  u64 = external_exports.number().int().min(0).max(Number.MAX_SAFE_INTEGER);
4600
+ i32 = external_exports.number().int().min(-2147483648).max(2147483647);
4600
4601
  bool = external_exports.boolean();
4601
4602
  ts = external_exports.string().refine(isProtocolTimestamp, "protocol timestamp");
4602
4603
  json = external_exports.unknown();
@@ -4704,6 +4705,15 @@ var init_envelope = __esm({
4704
4705
  tool_status: external_exports.enum(TOOL_STATUSES).optional(),
4705
4706
  tool_error_class: short.optional(),
4706
4707
  tool_error_message_digest: digest.optional(),
4708
+ /**
4709
+ * The exit code a shell command ended with, as the harness reported it
4710
+ * (#7158). Claude Code writes it at the start of a failed call's error
4711
+ * text ("Exit code 1"), Codex in its `exec_command_end` record, and Cursor
4712
+ * in `afterShellExecution`. Signed, because a process killed by a signal
4713
+ * can report a negative code. Absent when the harness did not say, which
4714
+ * is not the same as zero.
4715
+ */
4716
+ tool_exit_code: i32.optional(),
4707
4717
  tool_duration_ms: u32.optional(),
4708
4718
  tool_blocked_on_user_ms: u32.optional(),
4709
4719
  tool_is_mutating: bool.optional(),
@@ -8242,7 +8252,7 @@ function verifyBundle(bundle2, publicKeyPem, expectedHostEnrollmentId) {
8242
8252
  createPublicKey(publicKeyPem),
8243
8253
  Buffer.from(signature.sig, "base64")
8244
8254
  );
8245
- if (!ok) return { ok, reason: "signature does not verify" };
8255
+ if (!ok) return { ok, reason: "the lock does not verify" };
8246
8256
  if (expectedHostEnrollmentId !== void 0 && bundle2.host_enrollment_id !== expectedHostEnrollmentId) {
8247
8257
  return {
8248
8258
  ok: false,
@@ -10398,6 +10408,7 @@ var init_paths = __esm({
10398
10408
  backfillCursor: "backfill-cursor.json",
10399
10409
  memoryCounts: "memory-counts.json",
10400
10410
  stellaMemoryCursors: "stella-memory-cursors.json",
10411
+ memorySent: "memory-sent.json",
10401
10412
  preSessionCopies: "pre-session",
10402
10413
  stellaIdentity: "stella-identity",
10403
10414
  workOrders: "work-orders"
@@ -10704,7 +10715,7 @@ function verifyBytes(pinned, bytes, signature) {
10704
10715
  return ok ? { ok } : {
10705
10716
  ok,
10706
10717
  reason: "signature_invalid",
10707
- detail: "signature does not verify"
10718
+ detail: "the lock does not verify"
10708
10719
  };
10709
10720
  } catch (error) {
10710
10721
  return {
@@ -10793,7 +10804,7 @@ function verifyKeySet(set, pinned) {
10793
10804
  let last = {
10794
10805
  ok: false,
10795
10806
  reason: "unknown_kid",
10796
- detail: "no signature on the key set is by a pinned key"
10807
+ detail: "no lock on the key set is by a pinned key"
10797
10808
  };
10798
10809
  for (const signature of signatures) {
10799
10810
  if (!pinned.has(signature.kid)) continue;
@@ -14616,6 +14627,9 @@ var init_llm_call_dedupe = __esm({
14616
14627
  });
14617
14628
 
14618
14629
  // ../../packages/tacho/src/claude-code/backfill.ts
14630
+ function isMidTurnMessage(record) {
14631
+ return record["type"] === "attachment" && nonEmptyString(asRecord(record["attachment"])?.["type"]) === "queued_command";
14632
+ }
14619
14633
  function emptyTally() {
14620
14634
  return {
14621
14635
  lines: 0,
@@ -14781,7 +14795,7 @@ var init_backfill = __esm({
14781
14795
  init_record_basis();
14782
14796
  init_context();
14783
14797
  init_llm_call_dedupe();
14784
- BACKFILL_NORMALIZER_VERSION = "1";
14798
+ BACKFILL_NORMALIZER_VERSION = "2";
14785
14799
  TESTED_CLAUDE_CODE_VERSIONS = {
14786
14800
  lowest: "2.1.263",
14787
14801
  highest: "2.1.281"
@@ -15103,11 +15117,12 @@ var init_backfill = __esm({
15103
15117
  count2(this.tally.drift.unknownTypes, "(none)");
15104
15118
  return void 0;
15105
15119
  }
15106
- if (IGNORED_TYPES.has(type) || type.startsWith("artifact-")) {
15120
+ const mapped = MAPPED_TYPES.has(type) || isMidTurnMessage(value);
15121
+ if (!mapped && (IGNORED_TYPES.has(type) || type.startsWith("artifact-"))) {
15107
15122
  count2(this.tally.recordsIgnored, type);
15108
15123
  return void 0;
15109
15124
  }
15110
- if (!MAPPED_TYPES.has(type)) {
15125
+ if (!mapped) {
15111
15126
  count2(this.tally.drift.unknownTypes, type);
15112
15127
  return void 0;
15113
15128
  }
@@ -17516,6 +17531,15 @@ var init_result = __esm({
17516
17531
  });
17517
17532
 
17518
17533
  // ../../packages/tacho/src/claude-code/transcript.ts
17534
+ function queuedText(value) {
17535
+ if (typeof value === "string") return value.length > 0 ? value : void 0;
17536
+ if (!Array.isArray(value)) return void 0;
17537
+ const text5 = value.map((block) => {
17538
+ const item = rec3(block);
17539
+ return s(item?.["type"]) === "text" ? s(item?.["text"]) : void 0;
17540
+ }).filter((t) => t !== void 0 && t.length > 0).join("\n");
17541
+ return text5.length > 0 ? text5 : void 0;
17542
+ }
17519
17543
  function rec3(value) {
17520
17544
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
17521
17545
  }
@@ -17830,6 +17854,34 @@ function normalizeTranscriptLine(line, fallbackTs) {
17830
17854
  ],
17831
17855
  totals: {}
17832
17856
  };
17857
+ case "attachment": {
17858
+ const attachment = rec3(record["attachment"]);
17859
+ if (s(attachment?.["type"]) !== QUEUED_COMMAND)
17860
+ return { drafts: [], totals: {} };
17861
+ const prompt = queuedText(attachment?.["prompt"]);
17862
+ if (prompt === void 0) return { drafts: [], totals: {} };
17863
+ const origin = promptOriginOf(attachment?.["origin"]);
17864
+ return {
17865
+ drafts: [
17866
+ {
17867
+ ...draft(
17868
+ "oxagen:message",
17869
+ {
17870
+ prompt_digest: digestText(prompt),
17871
+ prompt_length: prompt.length,
17872
+ ...defined({
17873
+ prompt_origin: origin,
17874
+ message_uuid: s(record["uuid"])
17875
+ })
17876
+ },
17877
+ { [PROMPT_DELIVERY_ATTR]: MID_TURN_DELIVERY }
17878
+ ),
17879
+ content: textContent(prompt)
17880
+ }
17881
+ ],
17882
+ totals: {}
17883
+ };
17884
+ }
17833
17885
  case "queue-operation": {
17834
17886
  const queued = s(record["content"]);
17835
17887
  return {
@@ -17898,7 +17950,7 @@ function normalizeTranscriptLine(line, fallbackTs) {
17898
17950
  return { drafts: [], totals: {} };
17899
17951
  }
17900
17952
  }
17901
- var SESSION_TITLE_MAX, INTERRUPT_MARKER2;
17953
+ var PROMPT_DELIVERY_ATTR, MID_TURN_DELIVERY, QUEUED_COMMAND, SESSION_TITLE_MAX, INTERRUPT_MARKER2;
17902
17954
  var init_transcript = __esm({
17903
17955
  "../../packages/tacho/src/claude-code/transcript.ts"() {
17904
17956
  "use strict";
@@ -17908,6 +17960,9 @@ var init_transcript = __esm({
17908
17960
  init_context();
17909
17961
  init_payload_members();
17910
17962
  init_tools();
17963
+ PROMPT_DELIVERY_ATTR = "oxagen.prompt_delivery";
17964
+ MID_TURN_DELIVERY = "mid_turn";
17965
+ QUEUED_COMMAND = "queued_command";
17911
17966
  SESSION_TITLE_MAX = 512;
17912
17967
  INTERRUPT_MARKER2 = "[Request interrupted by user";
17913
17968
  }
@@ -22704,7 +22759,7 @@ function progressLine(report) {
22704
22759
  function reportLines(report) {
22705
22760
  const lines = [];
22706
22761
  lines.push(
22707
- report.dry_run ? `Dry run with normalizer ${report.normalizer_version}. Nothing was sealed or sent.` : `Backfill with normalizer ${report.normalizer_version}.`
22762
+ report.dry_run ? `Dry run with normalizer ${report.normalizer_version}. Nothing was locked or sent.` : `Backfill with normalizer ${report.normalizer_version}.`
22708
22763
  );
22709
22764
  lines.push("", "Projects");
22710
22765
  for (const project2 of report.projects) {
@@ -22783,7 +22838,7 @@ function reportLines(report) {
22783
22838
  }
22784
22839
  lines.push(
22785
22840
  "",
22786
- `Bodies: the workspace keeps ${report.bodies.mode === "content_exact" ? "content" : "digests only"}, and ${number(report.bodies.shipped)} bodies ${report.dry_run ? "would be sent" : "were queued to send"}.`
22841
+ `Bodies: the workspace keeps ${report.bodies.mode === "content_exact" ? "content" : "hashes only"}, and ${number(report.bodies.shipped)} bodies ${report.dry_run ? "would be sent" : "were queued to send"}.`
22787
22842
  );
22788
22843
  return lines;
22789
22844
  }
@@ -26331,7 +26386,7 @@ async function restoreCredentials(host, deps, mode = "unenroll", only) {
26331
26386
  continue;
26332
26387
  }
26333
26388
  warnings.push(
26334
- `the ${provider} credential in custody cannot be read (${unreadable}). ${label2}'s run token was taken out anyway, since the gateway it worked at is being removed; set the ${provider} key in ${label2} by hand. The sealed store is left at ${deps.paths.credentials} in case the key file can be repaired`
26389
+ `the ${provider} credential in custody cannot be read (${unreadable}). ${label2}'s run token was taken out anyway, since the gateway it worked at is being removed; set the ${provider} key in ${label2} by hand. The encrypted store is left at ${deps.paths.credentials} in case the key file can be repaired`
26335
26390
  );
26336
26391
  }
26337
26392
  const state = await contract.restore(
@@ -26393,7 +26448,10 @@ async function acquireSubscriptionToken(options, deps) {
26393
26448
  const run3 = await io.runSetupToken(
26394
26449
  claude,
26395
26450
  (chunk2) => process.stdout.write(
26396
- chunk2.replace(/sk-ant-oat[A-Za-z0-9_-]*/g, "sk-ant-oat\u2026 (sent to Oxagen)")
26451
+ chunk2.replace(
26452
+ /sk-ant-oat[A-Za-z0-9_-]*/g,
26453
+ "sk-ant-oat\u2026 (sent to Oxagen)"
26454
+ )
26397
26455
  )
26398
26456
  );
26399
26457
  if (run3.token !== void 0)
@@ -26490,9 +26548,7 @@ async function ensureCodexLogin(deps) {
26490
26548
  }
26491
26549
  async function codexLogin(deps) {
26492
26550
  const store = deps.credentialStore;
26493
- const held = store?.status().some(
26494
- (c) => c.provider === "openai" && c.kind === "chatgpt"
26495
- );
26551
+ const held = store?.status().some((c) => c.provider === "openai" && c.kind === "chatgpt");
26496
26552
  if (held !== true) {
26497
26553
  const why = await ensureCodexLogin(deps);
26498
26554
  if (why !== void 0)
@@ -26569,10 +26625,7 @@ var init_credential = __esm({
26569
26625
  MODEL_CREDENTIAL_HARNESSES = [
26570
26626
  ...BROKERABLE_HARNESSES
26571
26627
  ];
26572
- CREDENTIAL_MODES = [
26573
- "brokered",
26574
- "passthrough"
26575
- ];
26628
+ CREDENTIAL_MODES = ["brokered", "passthrough"];
26576
26629
  STELLA_ANTHROPIC_KEY_ENV = "ANTHROPIC_API_KEY";
26577
26630
  CLAUDE_OAUTH_TOKEN_ENV = "CLAUDE_CODE_OAUTH_TOKEN";
26578
26631
  }
@@ -27344,7 +27397,7 @@ import { readFileSync as readFileSync10 } from "node:fs";
27344
27397
  import { dirname as dirname9, resolve as resolve3 } from "node:path";
27345
27398
  import { fileURLToPath } from "node:url";
27346
27399
  function readVersion() {
27347
- if (true) return "3.0.0";
27400
+ if (true) return "3.0.1-27";
27348
27401
  try {
27349
27402
  const here = dirname9(fileURLToPath(import.meta.url));
27350
27403
  const pkg = JSON.parse(
@@ -32786,7 +32839,7 @@ function printStatus(report, deps) {
32786
32839
  );
32787
32840
  if (claudeDesktop.otherServers > 0)
32788
32841
  deps.out(
32789
- ` ${claudeDesktop.otherServers} other MCP server(s): ${claudeDesktop.otherServerNames.join(", ")} \u2014 Oxagen does not see what they serve`
32842
+ ` ${claudeDesktop.otherServers} other MCP server(s): ${claudeDesktop.otherServerNames.join(", ")}. Oxagen does not see what they serve`
32790
32843
  );
32791
32844
  }
32792
32845
  if (codexHooks !== void 0) {
@@ -33423,6 +33476,7 @@ async function unenrollLocked(options, deps) {
33423
33476
  deps.paths.backfillCursor,
33424
33477
  deps.paths.memoryCounts,
33425
33478
  deps.paths.stellaMemoryCursors,
33479
+ deps.paths.memorySent,
33426
33480
  deps.paths.pid,
33427
33481
  deps.paths.daemonLauncher
33428
33482
  ])
@@ -34444,7 +34498,7 @@ ${problems.map((problem) => ` ${problem}`).join("\n")}`
34444
34498
  if (merged.changed) {
34445
34499
  deps.writeStellaHooks(merged.file);
34446
34500
  deps.out(
34447
- ` hooks written for ${stellaHookPresence(merged.file, host.host_enrollment_id).present.length} events (${file.format === "toml" ? "a managed block at the end of stella.toml; the rest of the file is untouched" : "command hooks in settings.json"}; Stella has no SessionEnd, so tachod seals a session when the stella process exits)`
34501
+ ` hooks written for ${stellaHookPresence(merged.file, host.host_enrollment_id).present.length} events (${file.format === "toml" ? "a managed block at the end of stella.toml; the rest of the file is untouched" : "command hooks in settings.json"}; Stella has no SessionEnd, so tachod locks a session's record when the stella process exits)`
34448
34502
  );
34449
34503
  } else {
34450
34504
  deps.out(" already present; nothing to change");
@@ -34787,7 +34841,7 @@ ${problems.map((problem) => ` ${problem}`).join("\n")}`
34787
34841
  }
34788
34842
  if (!existsSync16(deps.paths.deviceKey))
34789
34843
  warnings.push(
34790
- `the device key is missing from ${deps.paths.deviceKey} after enrollment, so the daemon cannot sign for this machine; run \`oxagen agent enroll --force\` to enroll it again`
34844
+ `the device key is missing from ${deps.paths.deviceKey} after enrollment, so the daemon cannot lock what this machine sends; run \`oxagen agent enroll --force\` to enroll it again`
34791
34845
  );
34792
34846
  for (const warning of warnings) deps.err(`warning: ${warning}`);
34793
34847
  const hooked = harnesses.filter((harness) => !unhooked.includes(harness));
@@ -35430,7 +35484,7 @@ async function exportCommand(options, deps) {
35430
35484
  const events = wal.read(uuid);
35431
35485
  const first = events[0];
35432
35486
  const last = events[events.length - 1];
35433
- return `${uuid} ${first?.session_id ?? "?"} ${events.length} events ${first?.ts ?? ""} .. ${last?.ts ?? ""}${last?.kind === "agent_stop" ? " sealed" : ""}`;
35487
+ return `${uuid} ${first?.session_id ?? "?"} ${events.length} events ${first?.ts ?? ""} .. ${last?.ts ?? ""}${last?.kind === "agent_stop" ? " locked" : ""}`;
35434
35488
  })
35435
35489
  );
35436
35490
  deps.out(
@@ -36426,7 +36480,7 @@ async function verify4(options, rootDeps) {
36426
36480
  };
36427
36481
  }
36428
36482
  deps.err(
36429
- `Session ${found.session_id} chained as ${found.session_uuid}: ${found.seq} events, sealed.`
36483
+ `Session ${found.session_id} chained as ${found.session_uuid}: ${found.seq} events, locked.`
36430
36484
  );
36431
36485
  return {
36432
36486
  ok: true,
@@ -36454,12 +36508,12 @@ var init_verify = __esm({
36454
36508
  stella: 45e3
36455
36509
  };
36456
36510
  ENDING_GRACE_MS = 3e4;
36457
- ENDING_DETAIL = "SessionEnd arrived, but the Oxagen collector had not finished the session's final worktree read. The chain seals once that read lands. Run `oxagen agent verify` again in a minute";
36511
+ ENDING_DETAIL = "SessionEnd arrived, but the Oxagen collector had not finished the session's final worktree read. The collector locks the session's record once that read lands. Run `oxagen agent verify` again in a minute";
36458
36512
  UNSEALED_DETAIL = {
36459
36513
  "claude-code": "session started but SessionEnd never arrived within the timeout",
36460
- codex: "session started but its final chain seal never arrived; check Codex Stop and SessionEnd hook delivery with `oxagen agent status`",
36461
- cursor: "session started but its final chain seal never arrived; check Cursor stop and sessionEnd hook delivery with `oxagen agent status`",
36462
- stella: "session started but was not sealed within the timeout; Stella sends no SessionEnd, so the Oxagen collector seals the chain once the stella process has exited and its sweep has run"
36514
+ codex: "session started but the final lock on its record never arrived; check Codex Stop and SessionEnd hook delivery with `oxagen agent status`",
36515
+ cursor: "session started but the final lock on its record never arrived; check Cursor stop and sessionEnd hook delivery with `oxagen agent status`",
36516
+ stella: "session started but its record was not locked within the timeout; Stella sends no SessionEnd, so the Oxagen collector locks the session's record once the stella process has exited and its sweep has run"
36463
36517
  };
36464
36518
  }
36465
36519
  });
@@ -36709,7 +36763,7 @@ function sandboxMeasurement(placement, guest) {
36709
36763
  ];
36710
36764
  if (!HOST_ID.test(placement.hostId) || !VM_ID.test(placement.vmId) || digests.some((digest6) => !DIGEST.test(digest6)))
36711
36765
  throw new Error(
36712
- "The sandbox placement or a measured digest is malformed; the agent was not started"
36766
+ "The sandbox placement or a measured hash is malformed; the agent was not started"
36713
36767
  );
36714
36768
  return {
36715
36769
  profile: SANDBOX_PROFILE,
@@ -36731,7 +36785,7 @@ function modalSandboxMeasurement(placement, guest) {
36731
36785
  ];
36732
36786
  if (placement.profile !== MODAL_SANDBOX_PROFILE || !MODAL_ENVIRONMENT.test(placement.modalEnvironment) || !MODAL_ID.test(placement.modalSandboxId) || !MODAL_ID.test(placement.imageId) || digests.some((digest6) => !DIGEST.test(digest6)))
36733
36787
  throw new Error(
36734
- "The Modal placement or a measured digest is malformed; the agent was not started"
36788
+ "The Modal placement or a measured hash is malformed; the agent was not started"
36735
36789
  );
36736
36790
  return {
36737
36791
  profile: MODAL_SANDBOX_PROFILE,
@@ -38671,7 +38725,7 @@ function containerArguments(spec) {
38671
38725
  if (!/^oxagen-contained-[a-f0-9]{32}$/.test(spec.name))
38672
38726
  throw new Error("Invalid contained container name");
38673
38727
  if (!/^sha256:[a-f0-9]{64}$/.test(spec.image))
38674
- throw new Error("Contained execution requires a resolved image digest");
38728
+ throw new Error("Contained execution requires a resolved image hash");
38675
38729
  if (!Number.isSafeInteger(spec.uid) || spec.uid <= 0 || !Number.isSafeInteger(spec.gid) || spec.gid < 0)
38676
38730
  throw new Error("Contained execution requires an unprivileged Linux user");
38677
38731
  if (!CONTAINED_HARNESSES.includes(spec.harness))
@@ -39204,12 +39258,12 @@ function readBaseLayerDigest(system) {
39204
39258
  const found = system.stat(BASE_LAYER_DIGEST_FILE);
39205
39259
  if (found === void 0 || !found.isFile || found.uid !== 0 || (found.mode & 18) !== 0)
39206
39260
  throw new Error(
39207
- "The sandbox has no root-owned base layer digest; the agent was not started"
39261
+ "The sandbox has no root-owned base layer hash; the agent was not started"
39208
39262
  );
39209
39263
  const digest6 = system.readFile(BASE_LAYER_DIGEST_FILE).toString("utf8").trim();
39210
39264
  if (!/^sha256:[a-f0-9]{64}$/.test(digest6))
39211
39265
  throw new Error(
39212
- "The sandbox's base layer digest is malformed; the agent was not started"
39266
+ "The sandbox's base layer hash is malformed; the agent was not started"
39213
39267
  );
39214
39268
  return digest6;
39215
39269
  }
@@ -46448,7 +46502,7 @@ function createGithubProxy(deps) {
46448
46502
  verdict = evaluate();
46449
46503
  }
46450
46504
  if (!deps.policy().verified) {
46451
- reply(res, 403, "The signed mandate did not verify");
46505
+ reply(res, 403, "The mandate's lock did not verify");
46452
46506
  return;
46453
46507
  }
46454
46508
  if (verdict.decision !== "allow" || !live(lease)) {
@@ -46813,6 +46867,163 @@ var init_hook_queues = __esm({
46813
46867
  }
46814
46868
  });
46815
46869
 
46870
+ // ../../packages/tacho/src/collector/memory-capture/memory-counts.ts
46871
+ function countsOf(state) {
46872
+ const counts2 = /* @__PURE__ */ new Map();
46873
+ if (typeof state !== "object" || state === null) return counts2;
46874
+ const record = state;
46875
+ if (record.schema !== MEMORY_COUNTS_STATE_SCHEMA) return counts2;
46876
+ if (typeof record.counts !== "object" || record.counts === null)
46877
+ return counts2;
46878
+ for (const [harness, paths] of Object.entries(
46879
+ record.counts
46880
+ )) {
46881
+ if (typeof paths !== "object" || paths === null) continue;
46882
+ for (const [path2, count12] of Object.entries(
46883
+ paths
46884
+ ))
46885
+ if (Number.isSafeInteger(count12) && count12 > 0)
46886
+ counts2.set(keyOf(harness, path2), count12);
46887
+ }
46888
+ return counts2;
46889
+ }
46890
+ function stateOf2(counts2) {
46891
+ const byHarness = {};
46892
+ for (const [key, count12] of counts2) {
46893
+ const split = key.indexOf("\n");
46894
+ const harness = key.slice(0, split);
46895
+ const path2 = key.slice(split + 1);
46896
+ (byHarness[harness] ??= {})[path2] = count12;
46897
+ }
46898
+ return JSON.stringify({
46899
+ schema: MEMORY_COUNTS_STATE_SCHEMA,
46900
+ counts: byHarness
46901
+ });
46902
+ }
46903
+ function fileStateStorage(path2, unparsed) {
46904
+ return {
46905
+ load: () => readJsonStateFile(path2, unparsed),
46906
+ save: (json2) => writeSensitiveFileAtomic(path2, json2)
46907
+ };
46908
+ }
46909
+ function stateSaver(storage, failed3) {
46910
+ let lastFailure;
46911
+ return (json2) => {
46912
+ try {
46913
+ storage.save(json2);
46914
+ lastFailure = void 0;
46915
+ } catch (error) {
46916
+ const detail = error instanceof Error ? error.message : String(error);
46917
+ if (detail === lastFailure) return;
46918
+ lastFailure = detail;
46919
+ failed3(detail);
46920
+ }
46921
+ };
46922
+ }
46923
+ function fileUseCountStorage(path2, log) {
46924
+ return fileStateStorage(
46925
+ path2,
46926
+ (movedTo) => log(
46927
+ movedTo === void 0 ? "memory counts: the saved counts did not parse and could not be moved aside; every count is reported from zero" : `memory counts: the saved counts did not parse; moved them to ${movedTo}, and every count is reported from zero`
46928
+ )
46929
+ );
46930
+ }
46931
+ function createUseCountLedger(deps) {
46932
+ let counts2 = /* @__PURE__ */ new Map();
46933
+ let blind = false;
46934
+ try {
46935
+ counts2 = countsOf(deps.storage.load());
46936
+ } catch (error) {
46937
+ blind = true;
46938
+ deps.log(
46939
+ `memory counts: the saved counts could not be read (${error instanceof Error ? error.message : String(error)}); no harness count is reported until the daemon restarts`
46940
+ );
46941
+ }
46942
+ const saveState = stateSaver(
46943
+ deps.storage,
46944
+ (detail) => deps.log(
46945
+ `memory counts: the counts could not be saved (${detail}); a restart reports the rises since the last save again`
46946
+ )
46947
+ );
46948
+ const save = () => saveState(stateOf2(counts2));
46949
+ return {
46950
+ rises: (reads) => {
46951
+ if (blind) return [];
46952
+ const rises = [];
46953
+ let changed = false;
46954
+ for (const read2 of reads) {
46955
+ const present = /* @__PURE__ */ new Set();
46956
+ for (const { path: path2, count: count12, lastUsedAt } of read2.counts) {
46957
+ if (!Number.isSafeInteger(count12) || count12 < 0) continue;
46958
+ const key = keyOf(read2.harness, path2);
46959
+ present.add(key);
46960
+ const base2 = counts2.get(key) ?? 0;
46961
+ if (count12 < base2) {
46962
+ if (count12 === 0) counts2.delete(key);
46963
+ else counts2.set(key, count12);
46964
+ changed = true;
46965
+ continue;
46966
+ }
46967
+ if (count12 === base2) continue;
46968
+ const rise = Math.min(count12 - base2, RISE_MAX);
46969
+ rises.push({
46970
+ harness: read2.harness,
46971
+ path: path2,
46972
+ count: rise,
46973
+ usedAt: lastUsedAt ?? new Date(deps.now()).toISOString(),
46974
+ through: base2 + rise
46975
+ });
46976
+ }
46977
+ const prefix = keyOf(read2.harness, read2.root);
46978
+ for (const key of [...counts2.keys()])
46979
+ if (key.startsWith(prefix) && !present.has(key)) {
46980
+ counts2.delete(key);
46981
+ changed = true;
46982
+ }
46983
+ }
46984
+ if (changed) save();
46985
+ return rises;
46986
+ },
46987
+ settle: (rises) => {
46988
+ if (rises.length === 0) return;
46989
+ for (const rise of rises)
46990
+ counts2.set(keyOf(rise.harness, rise.path), rise.through);
46991
+ save();
46992
+ }
46993
+ };
46994
+ }
46995
+ var MEMORY_COUNTS_STATE_SCHEMA, RISE_MAX, keyOf;
46996
+ var init_memory_counts = __esm({
46997
+ "../../packages/tacho/src/collector/memory-capture/memory-counts.ts"() {
46998
+ "use strict";
46999
+ init_fs();
47000
+ MEMORY_COUNTS_STATE_SCHEMA = "tacho.memory-counts.v1";
47001
+ RISE_MAX = 1e4;
47002
+ keyOf = (harness, path2) => `${harness}
47003
+ ${path2}`;
47004
+ }
47005
+ });
47006
+
47007
+ // ../../packages/tacho/src/collector/memory-capture/memory-send.ts
47008
+ function stillHeld(held, digest6, now) {
47009
+ return held !== void 0 && held.digest === digest6 && now - held.at < MEMORY_REFUSED_RETRY_MS;
47010
+ }
47011
+ var MemoryRateLimited, MEMORY_REFUSED_RETRY_MS;
47012
+ var init_memory_send = __esm({
47013
+ "../../packages/tacho/src/collector/memory-capture/memory-send.ts"() {
47014
+ "use strict";
47015
+ MemoryRateLimited = class extends Error {
47016
+ constructor(retryAfterMs2) {
47017
+ super("memory upload: the control plane answered 429");
47018
+ this.retryAfterMs = retryAfterMs2;
47019
+ this.name = "MemoryRateLimited";
47020
+ }
47021
+ retryAfterMs;
47022
+ };
47023
+ MEMORY_REFUSED_RETRY_MS = 60 * 6e4;
47024
+ }
47025
+ });
47026
+
46816
47027
  // ../../packages/tacho/src/collector/memory-capture/memory-reader.ts
46817
47028
  import { createRequire as createRequire2 } from "node:module";
46818
47029
  import { isAbsolute as isAbsolute10, join as join40, sep as sep7 } from "node:path";
@@ -46932,9 +47143,9 @@ function memoryTextOf(text5) {
46932
47143
  function sentDigest(entry2) {
46933
47144
  return digestBytes(
46934
47145
  JSON.stringify([
46935
- entry2.statement,
46936
- entry2.label ?? null,
46937
- entry2.summary ?? null,
47146
+ redactText(entry2.statement),
47147
+ entry2.label === void 0 ? null : redactText(entry2.label),
47148
+ entry2.summary === void 0 ? null : redactText(entry2.summary),
46938
47149
  entry2.memoryType ?? null,
46939
47150
  entry2.personal ?? null,
46940
47151
  entry2.repositoryDigests ?? null
@@ -46963,10 +47174,60 @@ function storedTextOf(memory) {
46963
47174
  ...memoryType !== void 0 ? { memoryType } : {}
46964
47175
  };
46965
47176
  }
47177
+ function timerWait(ms) {
47178
+ return new Promise((resolve28) => {
47179
+ setTimeout(() => resolve28(true), ms).unref?.();
47180
+ });
47181
+ }
47182
+ function sentMarksOf(saved) {
47183
+ const marks = /* @__PURE__ */ new Map();
47184
+ if (typeof saved !== "object" || saved === null) return marks;
47185
+ const state = saved;
47186
+ if (state.schema !== MEMORY_SENT_STATE_SCHEMA || !Array.isArray(state.sent))
47187
+ return marks;
47188
+ for (const pair2 of state.sent) {
47189
+ if (!Array.isArray(pair2) || pair2.length !== 2) continue;
47190
+ const [key, digest6] = pair2;
47191
+ if (typeof key !== "string" || typeof digest6 !== "string") continue;
47192
+ if (!digest6.startsWith("sha256:")) continue;
47193
+ marks.set(key, digest6);
47194
+ }
47195
+ return marks;
47196
+ }
46966
47197
  function createMemoryReader(deps) {
46967
47198
  const harnesses = deps.harnesses ?? HARNESS_MEMORY_LOCATIONS;
46968
47199
  const stores = deps.stores ?? [];
46969
- const sent = /* @__PURE__ */ new Map();
47200
+ const log = deps.log ?? (() => void 0);
47201
+ const now = deps.now ?? Date.now;
47202
+ const wait = deps.wait ?? timerWait;
47203
+ let sent = /* @__PURE__ */ new Map();
47204
+ if (deps.storage !== void 0) {
47205
+ try {
47206
+ sent = sentMarksOf(deps.storage.load());
47207
+ } catch (error) {
47208
+ log(
47209
+ `memory reader: the sent record could not be read (${error instanceof Error ? error.message : String(error)}); every memory is sent again`
47210
+ );
47211
+ }
47212
+ }
47213
+ let dirty = false;
47214
+ const saveState = deps.storage === void 0 ? void 0 : stateSaver(
47215
+ deps.storage,
47216
+ (detail) => log(
47217
+ `memory reader: the sent record could not be saved (${detail}); a restart sends the memories since the last save again`
47218
+ )
47219
+ );
47220
+ function persist() {
47221
+ if (!dirty || saveState === void 0) return;
47222
+ dirty = false;
47223
+ saveState(
47224
+ JSON.stringify({
47225
+ schema: MEMORY_SENT_STATE_SCHEMA,
47226
+ sent: [...sent].slice(0, MEMORY_SENT_SAVED_MAX)
47227
+ })
47228
+ );
47229
+ }
47230
+ const refused2 = /* @__PURE__ */ new Map();
46970
47231
  const uploading = /* @__PURE__ */ new Set();
46971
47232
  let running;
46972
47233
  async function list2(dir) {
@@ -47014,16 +47275,39 @@ function createMemoryReader(deps) {
47014
47275
  const whole = [];
47015
47276
  const read2 = /* @__PURE__ */ new Set();
47016
47277
  const seen = /* @__PURE__ */ new Set();
47278
+ let waited = 0;
47017
47279
  async function offer(entry2) {
47018
- const key = keyOf(entry2.harness, entry2.path);
47280
+ const key = keyOf2(entry2.harness, entry2.path);
47019
47281
  const digest6 = sentDigest(entry2);
47020
47282
  if (sent.get(key) === digest6) return true;
47021
- try {
47022
- await deps.send(entry2);
47023
- } catch {
47024
- return false;
47283
+ if (stillHeld(refused2.get(key), digest6, now())) return true;
47284
+ for (; ; ) {
47285
+ let outcome;
47286
+ try {
47287
+ outcome = await deps.send(entry2);
47288
+ } catch (error) {
47289
+ if (!(error instanceof MemoryRateLimited)) return false;
47290
+ const ms = Math.max(
47291
+ MEMORY_RATE_WAIT_MIN_MS,
47292
+ Math.min(
47293
+ error.retryAfterMs ?? MEMORY_RATE_WAIT_MAX_MS,
47294
+ MEMORY_RATE_WAIT_MAX_MS
47295
+ )
47296
+ );
47297
+ if (waited + ms > MEMORY_SCAN_WAIT_MAX_MS) return false;
47298
+ waited += ms;
47299
+ if (!await wait(ms)) return false;
47300
+ continue;
47301
+ }
47302
+ if (outcome === "refused") {
47303
+ refused2.set(key, { digest: digest6, at: now() });
47304
+ return true;
47305
+ }
47306
+ break;
47025
47307
  }
47308
+ refused2.delete(key);
47026
47309
  sent.set(key, digest6);
47310
+ dirty = true;
47027
47311
  count12 += 1;
47028
47312
  return true;
47029
47313
  }
@@ -47035,7 +47319,7 @@ function createMemoryReader(deps) {
47035
47319
  const file = await readAt2(location.harness, path2);
47036
47320
  if (file.kind === "absent" || file.kind === "empty") continue;
47037
47321
  paths.push(path2);
47038
- seen.add(keyOf(location.harness, path2));
47322
+ seen.add(keyOf2(location.harness, path2));
47039
47323
  if (file.kind !== "entry") continue;
47040
47324
  if (!await offer({ ...file.entry, ...placedFields(where) }))
47041
47325
  return false;
@@ -47052,7 +47336,7 @@ function createMemoryReader(deps) {
47052
47336
  for (const location of locations) {
47053
47337
  const top = location.projectsDir(deps.home);
47054
47338
  const root = withSep(top);
47055
- const prefix = keyOf(location.harness, root);
47339
+ const prefix = keyOf2(location.harness, root);
47056
47340
  if (read2.has(prefix)) continue;
47057
47341
  read2.add(prefix);
47058
47342
  if (scoper === void 0) continue;
@@ -47069,7 +47353,7 @@ function createMemoryReader(deps) {
47069
47353
  const paths2 = [];
47070
47354
  if (!await readFolder(location, dir, files2.names, where2, paths2))
47071
47355
  return { sent: count12 };
47072
- whole.push(keyOf(location.harness, folder));
47356
+ whole.push(keyOf2(location.harness, folder));
47073
47357
  scans.push({
47074
47358
  harness: location.harness,
47075
47359
  root: folder,
@@ -47097,7 +47381,7 @@ function createMemoryReader(deps) {
47097
47381
  scans.push({ harness: location.harness, root, paths: paths.sort() });
47098
47382
  }
47099
47383
  for (const store of typeof stores === "function" ? stores() : stores) {
47100
- const prefix = keyOf(store.harness, store.root);
47384
+ const prefix = keyOf2(store.harness, store.root);
47101
47385
  if (read2.has(prefix)) continue;
47102
47386
  read2.add(prefix);
47103
47387
  const found = await store.read();
@@ -47109,7 +47393,7 @@ function createMemoryReader(deps) {
47109
47393
  for (const memory of found.memories) {
47110
47394
  if (!memory.path.startsWith(store.root) || memory.path.length === store.root.length)
47111
47395
  continue;
47112
- const key = keyOf(store.harness, memory.path);
47396
+ const key = keyOf2(store.harness, memory.path);
47113
47397
  if (seen.has(key)) continue;
47114
47398
  const text5 = storedTextOf(memory);
47115
47399
  if (text5.statement.length === 0) continue;
@@ -47141,31 +47425,50 @@ function createMemoryReader(deps) {
47141
47425
  counts: useCounts
47142
47426
  });
47143
47427
  }
47428
+ const gone = (key) => !seen.has(key) && whole.some((prefix) => key.startsWith(prefix));
47144
47429
  for (const key of [...sent.keys()])
47145
- if (!seen.has(key) && whole.some((prefix) => key.startsWith(prefix)))
47430
+ if (gone(key)) {
47146
47431
  sent.delete(key);
47432
+ dirty = true;
47433
+ }
47434
+ for (const key of [...refused2.keys()]) if (gone(key)) refused2.delete(key);
47147
47435
  return { sent: count12, scans, counts: counts2 };
47148
47436
  }
47149
47437
  return {
47150
47438
  // A scan that overlaps one still running joins it, so no entry is sent
47151
- // twice at once.
47439
+ // twice at once. Every scan saves what it sent, whether it finished or
47440
+ // stopped on a failure.
47152
47441
  scan: () => {
47153
47442
  running ??= scanOnce().finally(() => {
47154
47443
  running = void 0;
47444
+ persist();
47155
47445
  });
47156
47446
  return running;
47157
47447
  },
47158
47448
  uploads: (path2) => {
47159
47449
  for (const root of uploading) if (path2.startsWith(root)) return true;
47160
47450
  return false;
47451
+ },
47452
+ resend: (memories) => {
47453
+ for (const memory of memories)
47454
+ if (sent.delete(keyOf2(memory.harness, memory.path))) dirty = true;
47455
+ persist();
47161
47456
  }
47162
47457
  };
47163
47458
  }
47164
- var MEMORY_STATEMENT_MAX_CHARS, MEMORY_LABEL_MAX_CHARS, MEMORY_SUMMARY_MAX_CHARS, MEMORY_TYPE_PATTERN, MEMORY_PROJECT_DIRS_MAX, HARNESS_MEMORY_LOCATIONS, FRONTMATTER, sqliteModule, FRONTMATTER_LINE, sends, keyOf, withSep;
47459
+ var MEMORY_SENT_STATE_SCHEMA, MEMORY_SENT_SAVED_MAX, MEMORY_RATE_WAIT_MAX_MS, MEMORY_RATE_WAIT_MIN_MS, MEMORY_SCAN_WAIT_MAX_MS, MEMORY_STATEMENT_MAX_CHARS, MEMORY_LABEL_MAX_CHARS, MEMORY_SUMMARY_MAX_CHARS, MEMORY_TYPE_PATTERN, MEMORY_PROJECT_DIRS_MAX, HARNESS_MEMORY_LOCATIONS, FRONTMATTER, sqliteModule, FRONTMATTER_LINE, sends, keyOf2, withSep;
47165
47460
  var init_memory_reader = __esm({
47166
47461
  "../../packages/tacho/src/collector/memory-capture/memory-reader.ts"() {
47167
47462
  "use strict";
47168
47463
  init_digest();
47464
+ init_redaction();
47465
+ init_memory_counts();
47466
+ init_memory_send();
47467
+ MEMORY_SENT_STATE_SCHEMA = "tacho.memory-sent.v1";
47468
+ MEMORY_SENT_SAVED_MAX = 5e4;
47469
+ MEMORY_RATE_WAIT_MAX_MS = 6e4;
47470
+ MEMORY_RATE_WAIT_MIN_MS = 1e3;
47471
+ MEMORY_SCAN_WAIT_MAX_MS = 30 * 6e4;
47169
47472
  MEMORY_STATEMENT_MAX_CHARS = 2e3;
47170
47473
  MEMORY_LABEL_MAX_CHARS = 200;
47171
47474
  MEMORY_SUMMARY_MAX_CHARS = 1e3;
@@ -47182,7 +47485,7 @@ var init_memory_reader = __esm({
47182
47485
  FRONTMATTER = /^---[ \t]*\r?\n(?:([\s\S]*?)\r?\n)?---[ \t]*(?:\r?\n|$)/;
47183
47486
  FRONTMATTER_LINE = /^([ \t]*)([A-Za-z_][\w-]*)[ \t]*:[ \t]*(.*)$/;
47184
47487
  sends = (where) => where.kind === "personal" || where.kind === "repository";
47185
- keyOf = (harness, path2) => `${harness}
47488
+ keyOf2 = (harness, path2) => `${harness}
47186
47489
  ${path2}`;
47187
47490
  withSep = (dir) => dir.endsWith(sep7) ? dir : `${dir}${sep7}`;
47188
47491
  }
@@ -47290,144 +47593,21 @@ var init_codex_store = __esm({
47290
47593
  }
47291
47594
  });
47292
47595
 
47293
- // ../../packages/tacho/src/collector/memory-capture/memory-counts.ts
47294
- function countsOf(state) {
47295
- const counts2 = /* @__PURE__ */ new Map();
47296
- if (typeof state !== "object" || state === null) return counts2;
47297
- const record = state;
47298
- if (record.schema !== MEMORY_COUNTS_STATE_SCHEMA) return counts2;
47299
- if (typeof record.counts !== "object" || record.counts === null)
47300
- return counts2;
47301
- for (const [harness, paths] of Object.entries(
47302
- record.counts
47303
- )) {
47304
- if (typeof paths !== "object" || paths === null) continue;
47305
- for (const [path2, count12] of Object.entries(
47306
- paths
47307
- ))
47308
- if (Number.isSafeInteger(count12) && count12 > 0)
47309
- counts2.set(keyOf2(harness, path2), count12);
47310
- }
47311
- return counts2;
47312
- }
47313
- function stateOf2(counts2) {
47314
- const byHarness = {};
47315
- for (const [key, count12] of counts2) {
47316
- const split = key.indexOf("\n");
47317
- const harness = key.slice(0, split);
47318
- const path2 = key.slice(split + 1);
47319
- (byHarness[harness] ??= {})[path2] = count12;
47320
- }
47321
- return JSON.stringify({
47322
- schema: MEMORY_COUNTS_STATE_SCHEMA,
47323
- counts: byHarness
47324
- });
47325
- }
47326
- function fileStateStorage(path2, unparsed) {
47327
- return {
47328
- load: () => readJsonStateFile(path2, unparsed),
47329
- save: (json2) => writeSensitiveFileAtomic(path2, json2)
47330
- };
47331
- }
47332
- function stateSaver(storage, failed3) {
47333
- let lastFailure;
47334
- return (json2) => {
47335
- try {
47336
- storage.save(json2);
47337
- lastFailure = void 0;
47338
- } catch (error) {
47339
- const detail = error instanceof Error ? error.message : String(error);
47340
- if (detail === lastFailure) return;
47341
- lastFailure = detail;
47342
- failed3(detail);
47343
- }
47344
- };
47345
- }
47346
- function fileUseCountStorage(path2, log) {
47347
- return fileStateStorage(
47348
- path2,
47349
- (movedTo) => log(
47350
- movedTo === void 0 ? "memory counts: the saved counts did not parse and could not be moved aside; every count is reported from zero" : `memory counts: the saved counts did not parse; moved them to ${movedTo}, and every count is reported from zero`
47351
- )
47352
- );
47353
- }
47354
- function createUseCountLedger(deps) {
47355
- let counts2 = /* @__PURE__ */ new Map();
47356
- let blind = false;
47596
+ // ../../packages/tacho/src/collector/memory-capture/memory-upload.ts
47597
+ function answerReason(text5) {
47598
+ let reason3 = text5;
47357
47599
  try {
47358
- counts2 = countsOf(deps.storage.load());
47359
- } catch (error) {
47360
- blind = true;
47361
- deps.log(
47362
- `memory counts: the saved counts could not be read (${error instanceof Error ? error.message : String(error)}); no harness count is reported until the daemon restarts`
47363
- );
47364
- }
47365
- const saveState = stateSaver(
47366
- deps.storage,
47367
- (detail) => deps.log(
47368
- `memory counts: the counts could not be saved (${detail}); a restart reports the rises since the last save again`
47369
- )
47370
- );
47371
- const save = () => saveState(stateOf2(counts2));
47372
- return {
47373
- rises: (reads) => {
47374
- if (blind) return [];
47375
- const rises = [];
47376
- let changed = false;
47377
- for (const read2 of reads) {
47378
- const present = /* @__PURE__ */ new Set();
47379
- for (const { path: path2, count: count12, lastUsedAt } of read2.counts) {
47380
- if (!Number.isSafeInteger(count12) || count12 < 0) continue;
47381
- const key = keyOf2(read2.harness, path2);
47382
- present.add(key);
47383
- const base2 = counts2.get(key) ?? 0;
47384
- if (count12 < base2) {
47385
- if (count12 === 0) counts2.delete(key);
47386
- else counts2.set(key, count12);
47387
- changed = true;
47388
- continue;
47389
- }
47390
- if (count12 === base2) continue;
47391
- const rise = Math.min(count12 - base2, RISE_MAX);
47392
- rises.push({
47393
- harness: read2.harness,
47394
- path: path2,
47395
- count: rise,
47396
- usedAt: lastUsedAt ?? new Date(deps.now()).toISOString(),
47397
- through: base2 + rise
47398
- });
47399
- }
47400
- const prefix = keyOf2(read2.harness, read2.root);
47401
- for (const key of [...counts2.keys()])
47402
- if (key.startsWith(prefix) && !present.has(key)) {
47403
- counts2.delete(key);
47404
- changed = true;
47405
- }
47406
- }
47407
- if (changed) save();
47408
- return rises;
47409
- },
47410
- settle: (rises) => {
47411
- if (rises.length === 0) return;
47412
- for (const rise of rises)
47413
- counts2.set(keyOf2(rise.harness, rise.path), rise.through);
47414
- save();
47600
+ const parsed2 = JSON.parse(text5);
47601
+ if (typeof parsed2 === "object" && parsed2 !== null) {
47602
+ const body2 = parsed2;
47603
+ const message = typeof body2.message === "string" ? body2.message : typeof body2.error === "object" && body2.error !== null && typeof body2.error.message === "string" ? body2.error.message : void 0;
47604
+ reason3 = message ?? "";
47415
47605
  }
47416
- };
47417
- }
47418
- var MEMORY_COUNTS_STATE_SCHEMA, RISE_MAX, keyOf2;
47419
- var init_memory_counts = __esm({
47420
- "../../packages/tacho/src/collector/memory-capture/memory-counts.ts"() {
47421
- "use strict";
47422
- init_fs();
47423
- MEMORY_COUNTS_STATE_SCHEMA = "tacho.memory-counts.v1";
47424
- RISE_MAX = 1e4;
47425
- keyOf2 = (harness, path2) => `${harness}
47426
- ${path2}`;
47606
+ } catch {
47427
47607
  }
47428
- });
47429
-
47430
- // ../../packages/tacho/src/collector/memory-capture/memory-upload.ts
47608
+ const line = reason3.replace(/\s+/g, " ").trim();
47609
+ return line.length === 0 ? void 0 : clip2(line, REFUSAL_REASON_MAX_CHARS);
47610
+ }
47431
47611
  async function postToControlPlane(fetch2, host, path2, body2, signal) {
47432
47612
  const url = `${host.api_url.replace(/\/$/, "")}${path2}`;
47433
47613
  const payload = JSON.stringify({
@@ -47444,10 +47624,15 @@ async function postToControlPlane(fetch2, host, path2, body2, signal) {
47444
47624
  body: payload,
47445
47625
  signal
47446
47626
  });
47627
+ const retryAfterMs2 = parseRetryAfter(
47628
+ response.headers?.get("retry-after") ?? null,
47629
+ Date.now()
47630
+ );
47447
47631
  return {
47448
47632
  ok: response.ok,
47449
47633
  status: response.status,
47450
- text: await response.text()
47634
+ text: await response.text(),
47635
+ ...retryAfterMs2 !== void 0 ? { retryAfterMs: retryAfterMs2 } : {}
47451
47636
  };
47452
47637
  }
47453
47638
  function changedFailureLog(write) {
@@ -47503,7 +47688,7 @@ function createMemoryUpload(deps) {
47503
47688
  const status2 = answer.status;
47504
47689
  if (answer.ok) {
47505
47690
  failures.clear();
47506
- return;
47691
+ return "stored";
47507
47692
  }
47508
47693
  if (status2 === 404) {
47509
47694
  if (!routeMissingLogged) {
@@ -47515,24 +47700,32 @@ function createMemoryUpload(deps) {
47515
47700
  throw new Error("memory upload: the control plane answered 404");
47516
47701
  }
47517
47702
  if (ENTRY_REFUSED.has(status2)) {
47703
+ const reason3 = answerReason(answer.text);
47518
47704
  deps.log(
47519
- `memory upload: the control plane refused ${entry2.path} (${status2}); it is sent again when the file changes`
47705
+ `memory upload: the control plane refused ${entry2.path} (${status2}${reason3 === void 0 ? "" : `: ${reason3}`}); it is held and sent again later`
47520
47706
  );
47521
- return;
47707
+ return "refused";
47708
+ }
47709
+ if (status2 === 429) {
47710
+ failure4(`the control plane answered ${status2}`);
47711
+ throw new MemoryRateLimited(answer.retryAfterMs);
47522
47712
  }
47523
47713
  throw failure4(`the control plane answered ${status2}`);
47524
47714
  };
47525
47715
  }
47526
- var MEMORY_UPLOAD_PATH, MEMORY_UPLOAD_TIMEOUT_MS, ENTRY_REFUSED;
47716
+ var MEMORY_UPLOAD_PATH, MEMORY_UPLOAD_TIMEOUT_MS, ENTRY_REFUSED, REFUSAL_REASON_MAX_CHARS;
47527
47717
  var init_memory_upload = __esm({
47528
47718
  "../../packages/tacho/src/collector/memory-capture/memory-upload.ts"() {
47529
47719
  "use strict";
47530
47720
  init_redaction();
47721
+ init_control_client();
47531
47722
  init_request_signature();
47532
47723
  init_memory_reader();
47724
+ init_memory_send();
47533
47725
  MEMORY_UPLOAD_PATH = "/v1/tacho/memories";
47534
47726
  MEMORY_UPLOAD_TIMEOUT_MS = 15e3;
47535
47727
  ENTRY_REFUSED = /* @__PURE__ */ new Set([400, 413, 422]);
47728
+ REFUSAL_REASON_MAX_CHARS = 300;
47536
47729
  }
47537
47730
  });
47538
47731
 
@@ -47907,6 +48100,26 @@ function pendingOf(text5, sentCount) {
47907
48100
  (index) => Number.isInteger(index) && index >= 0 && index < sentCount
47908
48101
  );
47909
48102
  }
48103
+ function missingOf(text5, listed) {
48104
+ let parsed2;
48105
+ try {
48106
+ parsed2 = JSON.parse(text5);
48107
+ } catch {
48108
+ return [];
48109
+ }
48110
+ const missing = typeof parsed2 === "object" && parsed2 !== null ? parsed2.missing : void 0;
48111
+ if (!Array.isArray(missing)) return [];
48112
+ const found = [];
48113
+ for (const item of missing) {
48114
+ if (typeof item !== "object" || item === null) continue;
48115
+ const { harness, path: path2 } = item;
48116
+ if (typeof harness !== "string" || typeof path2 !== "string") continue;
48117
+ if (!listed.has(`${harness}
48118
+ ${path2}`)) continue;
48119
+ found.push({ harness, path: path2 });
48120
+ }
48121
+ return found;
48122
+ }
47910
48123
  function createMemoryUses(deps) {
47911
48124
  const queue = /* @__PURE__ */ new Map();
47912
48125
  let indexQueued = 0;
@@ -47936,7 +48149,7 @@ function createMemoryUses(deps) {
47936
48149
  }
47937
48150
  enqueue(key, { ...use });
47938
48151
  }
47939
- async function call2(body2, uses) {
48152
+ async function call2(body2, uses, listed = /* @__PURE__ */ new Set()) {
47940
48153
  let response;
47941
48154
  try {
47942
48155
  response = await postToControlPlane(
@@ -47954,7 +48167,11 @@ function createMemoryUses(deps) {
47954
48167
  }
47955
48168
  if (response.ok) {
47956
48169
  failures.clear();
47957
- return { kind: "taken", pending: pendingOf(response.text, uses) };
48170
+ return {
48171
+ kind: "taken",
48172
+ pending: pendingOf(response.text, uses),
48173
+ missing: missingOf(response.text, listed)
48174
+ };
47958
48175
  }
47959
48176
  if (response.status === 404) {
47960
48177
  if (!routeMissingLogged) {
@@ -47971,6 +48188,7 @@ function createMemoryUses(deps) {
47971
48188
  return { kind: "kept" };
47972
48189
  }
47973
48190
  async function reportOnce(scans, counts2) {
48191
+ const missing = [];
47974
48192
  if (overflowed > 0) {
47975
48193
  deps.log(
47976
48194
  `memory uses: the queue was full, so ${overflowed} memory uses were not counted`
@@ -48009,7 +48227,7 @@ function createMemoryUses(deps) {
48009
48227
  if (result2.kind === "kept") {
48010
48228
  for (const rest of batches.slice(position))
48011
48229
  for (const use of rest) requeue(use);
48012
- return;
48230
+ return { missing };
48013
48231
  }
48014
48232
  if (result2.kind === "refused") {
48015
48233
  deps.log(
@@ -48037,7 +48255,7 @@ function createMemoryUses(deps) {
48037
48255
  },
48038
48256
  0
48039
48257
  );
48040
- if (result2.kind === "kept") return;
48258
+ if (result2.kind === "kept") return { missing };
48041
48259
  if (result2.kind === "refused")
48042
48260
  deps.log(
48043
48261
  `memory uses: the control plane refused ${batch.length} harness counts (${result2.status}); they are dropped`
@@ -48054,16 +48272,22 @@ function createMemoryUses(deps) {
48054
48272
  );
48055
48273
  }
48056
48274
  for (let start = 0; start < lists.length; start += MEMORY_SCANS_PER_REPORT) {
48057
- const result2 = await call2(
48058
- { scans: lists.slice(start, start + MEMORY_SCANS_PER_REPORT) },
48059
- 0
48275
+ const chunk2 = lists.slice(start, start + MEMORY_SCANS_PER_REPORT);
48276
+ const listed = new Set(
48277
+ chunk2.flatMap(
48278
+ (scan) => scan.paths.map((path2) => `${scan.harness}
48279
+ ${path2}`)
48280
+ )
48060
48281
  );
48061
- if (result2.kind === "kept") return;
48282
+ const result2 = await call2({ scans: chunk2 }, 0, listed);
48283
+ if (result2.kind === "kept") return { missing };
48062
48284
  if (result2.kind === "refused")
48063
48285
  deps.log(
48064
48286
  `memory uses: the control plane refused a scan's file list (${result2.status})`
48065
48287
  );
48288
+ else missing.push(...result2.missing);
48066
48289
  }
48290
+ return { missing };
48067
48291
  }
48068
48292
  return {
48069
48293
  note: (read2) => {
@@ -48094,6 +48318,7 @@ function createMemoryUses(deps) {
48094
48318
  deps.log(
48095
48319
  `memory uses: the report failed (${error instanceof Error ? error.message : String(error)})`
48096
48320
  );
48321
+ return { missing: [] };
48097
48322
  }).finally(() => {
48098
48323
  running = void 0;
48099
48324
  });
@@ -48344,6 +48569,7 @@ function createStellaMemories(deps) {
48344
48569
  }
48345
48570
  const gone = /* @__PURE__ */ new Set();
48346
48571
  const sent = /* @__PURE__ */ new Map();
48572
+ const refused2 = /* @__PURE__ */ new Map();
48347
48573
  const failures = /* @__PURE__ */ new Map();
48348
48574
  const viewsMissingLogged = /* @__PURE__ */ new Set();
48349
48575
  let running;
@@ -48443,12 +48669,19 @@ ${lineage}`;
48443
48669
  const key = sentKey(store, memory.lineage);
48444
48670
  const digest6 = sentDigest2(memory);
48445
48671
  if (sent.get(key) === digest6) continue;
48672
+ if (stillHeld(refused2.get(key), digest6, deps.now())) continue;
48673
+ let outcome;
48446
48674
  try {
48447
- await deps.send(entryOf2(memory, store));
48675
+ outcome = await deps.send(entryOf2(memory, store));
48448
48676
  } catch {
48449
48677
  sending = false;
48450
48678
  break;
48451
48679
  }
48680
+ if (outcome === "refused") {
48681
+ refused2.set(key, { digest: digest6, at: deps.now() });
48682
+ continue;
48683
+ }
48684
+ refused2.delete(key);
48452
48685
  sent.set(key, digest6);
48453
48686
  result2.sent += 1;
48454
48687
  }
@@ -48504,6 +48737,11 @@ ${lineage}`;
48504
48737
  running = void 0;
48505
48738
  });
48506
48739
  return running;
48740
+ },
48741
+ resend: (lineages) => {
48742
+ const wanted = new Set(lineages);
48743
+ for (const key of [...sent.keys()])
48744
+ if (wanted.has(key.slice(key.indexOf("\n") + 1))) sent.delete(key);
48507
48745
  }
48508
48746
  };
48509
48747
  }
@@ -48513,6 +48751,7 @@ var init_stella_memories = __esm({
48513
48751
  "use strict";
48514
48752
  init_digest();
48515
48753
  init_memory_counts();
48754
+ init_memory_send();
48516
48755
  init_memory_uses();
48517
48756
  init_stella_store();
48518
48757
  STELLA_CURSORS_STATE_SCHEMA = "tacho.stella-memory-cursors.v1";
@@ -48523,7 +48762,7 @@ var init_stella_memories = __esm({
48523
48762
  function digestMismatch() {
48524
48763
  return {
48525
48764
  code: "digest_mismatch",
48526
- message: "The package digest does not match the lock.",
48765
+ message: "The package hash does not match the lock.",
48527
48766
  fix: "Reinstall the locked version, or run the sync if the package changed on purpose."
48528
48767
  };
48529
48768
  }
@@ -48566,7 +48805,7 @@ function envelopeInvalid(reason3, subject = "call") {
48566
48805
  return {
48567
48806
  code: "envelope_invalid",
48568
48807
  message: `The ${subject}'s envelope does not verify: ${reason3}.`,
48569
- fix: "Enroll this machine again if Oxagen rotated its signing key, then retry."
48808
+ fix: "Enroll this machine again if Oxagen changed the key it locks envelopes with, then retry."
48570
48809
  };
48571
48810
  }
48572
48811
  function envelopeExpired(expiresAt, subject = "call") {
@@ -48580,7 +48819,7 @@ function envelopeReplayed(subject = "call") {
48580
48819
  return {
48581
48820
  code: "envelope_replayed",
48582
48821
  message: `The local gateway already ran a ${subject} with this envelope's nonce.`,
48583
- fix: `Retry the ${subject}. The cloud gateway signs each ${subject} with a new nonce.`
48822
+ fix: `Retry the ${subject}. The cloud gateway gives each ${subject} a new nonce.`
48584
48823
  };
48585
48824
  }
48586
48825
  function wrongMachine(machine, subject = "call") {
@@ -48594,7 +48833,7 @@ function argumentsMismatch() {
48594
48833
  return {
48595
48834
  code: "arguments_mismatch",
48596
48835
  message: "The call's arguments do not hash to the envelope's arguments_hash.",
48597
- fix: "Retry the call. The local gateway runs only the arguments the cloud gateway signed."
48836
+ fix: "Retry the call. The local gateway runs only the arguments the cloud gateway locked into the envelope."
48598
48837
  };
48599
48838
  }
48600
48839
  function launchMismatch(reason3) {
@@ -48705,7 +48944,7 @@ var init_wire2 = __esm({
48705
48944
  LOCAL_DISCOVERY_ENVELOPE_SCHEMA = "local-discovery-envelope/v1";
48706
48945
  ENVELOPE_TTL_MAX_MS = 3e4;
48707
48946
  DEFAULT_DEADLINE_MS = 3e4;
48708
- sha256Schema = external_exports.string().regex(SHA256_DIGEST_PATTERN, "not a sha256:<hex> digest");
48947
+ sha256Schema = external_exports.string().regex(SHA256_DIGEST_PATTERN, "not a sha256:<hex> hash");
48709
48948
  machineIdSchema = external_exports.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "not a machine id");
48710
48949
  nonceSchema = external_exports.string().regex(/^[A-Za-z0-9_-]{22,64}$/, "a nonce is 22 to 64 base64url characters");
48711
48950
  envVarNameSchema = external_exports.string().regex(/^[A-Za-z_][A-Za-z0-9_]{0,127}$/, "not an environment variable name");
@@ -48719,7 +48958,7 @@ var init_wire2 = __esm({
48719
48958
  alg: external_exports.literal("ed25519"),
48720
48959
  sig: external_exports.string().regex(
48721
48960
  /^[A-Za-z0-9+/]{86}==$/,
48722
- "an Ed25519 signature is 64 bytes in padded base64"
48961
+ "an Ed25519 lock is 64 bytes in padded base64"
48723
48962
  )
48724
48963
  }).strict();
48725
48964
  localCallEnvelopeSchema = external_exports.object({
@@ -49085,7 +49324,7 @@ function createPackageDigester(deps) {
49085
49324
  const pinned = args.find((arg) => arg.startsWith(prefix))?.slice(prefix.length);
49086
49325
  if (pinned === void 0 || !SHA256_DIGEST_PATTERN.test(pinned)) {
49087
49326
  throw new DigestProblem(
49088
- `the launch does not pull ${pkg.name} by a sha256 digest`
49327
+ `the launch does not pull ${pkg.name} by a sha256 hash`
49089
49328
  );
49090
49329
  }
49091
49330
  return pinned;
@@ -49220,7 +49459,7 @@ function checkSignedEnvelope(envelope2, launch, options, subject) {
49220
49459
  if (signature.alg !== "ed25519") {
49221
49460
  return refuse(
49222
49461
  envelopeInvalid(
49223
- `it is signed with ${String(signature.alg)}, and this machine accepts only ed25519`,
49462
+ `it is locked with ${String(signature.alg)}, and this machine accepts only ed25519`,
49224
49463
  subject
49225
49464
  )
49226
49465
  );
@@ -49229,14 +49468,14 @@ function checkSignedEnvelope(envelope2, launch, options, subject) {
49229
49468
  if (signature.key_id !== trusted) {
49230
49469
  return refuse(
49231
49470
  envelopeInvalid(
49232
- `it names signing key ${signature.key_id}, and this machine trusts key ${trusted}`,
49471
+ `it was locked with key ${signature.key_id}, and this machine trusts key ${trusted}`,
49233
49472
  subject
49234
49473
  )
49235
49474
  );
49236
49475
  }
49237
49476
  if (!signatureVerifies(envelope2, options.publicKeyPem)) {
49238
49477
  return refuse(
49239
- envelopeInvalid("the signature does not match its contents", subject)
49478
+ envelopeInvalid("its lock does not match its contents", subject)
49240
49479
  );
49241
49480
  }
49242
49481
  if (envelope2.machine !== options.machine)
@@ -49266,7 +49505,7 @@ function checkSignedEnvelope(envelope2, launch, options, subject) {
49266
49505
  if (launch.package.digest !== envelope2.package_digest) {
49267
49506
  return refuse(
49268
49507
  launchMismatch(
49269
- `the launch pins package digest ${launch.package.digest}, and the envelope signs ${envelope2.package_digest}`
49508
+ `the launch pins package hash ${launch.package.digest}, and the envelope locks ${envelope2.package_digest}`
49270
49509
  )
49271
49510
  );
49272
49511
  }
@@ -49274,7 +49513,7 @@ function checkSignedEnvelope(envelope2, launch, options, subject) {
49274
49513
  if (launchDigest !== envelope2.launch_digest) {
49275
49514
  return refuse(
49276
49515
  launchMismatch(
49277
- `the launch's command, args, and env names hash to ${launchDigest}, and the envelope signs ${envelope2.launch_digest}`
49516
+ `the launch's command, args, and env names hash to ${launchDigest}, and the envelope locks ${envelope2.launch_digest}`
49278
49517
  )
49279
49518
  );
49280
49519
  }
@@ -50441,7 +50680,7 @@ async function fetchOne(input, url) {
50441
50680
  Buffer.from(await sum3.arrayBuffer()).toString("utf8")
50442
50681
  );
50443
50682
  if (want === void 0)
50444
- return { ok: false, message: `${url}.sha256 names no SHA-256 digest` };
50683
+ return { ok: false, message: `${url}.sha256 names no SHA-256 hash` };
50445
50684
  const file = await input.fetch(url, {
50446
50685
  signal: AbortSignal.timeout(timeoutMs)
50447
50686
  });
@@ -53440,7 +53679,7 @@ function createModelProxy(deps) {
53440
53679
  let session;
53441
53680
  const lost = (error) => {
53442
53681
  deps.log(
53443
- `model proxy: sealing the frame of a call it did not forward (${reason3}) failed: ${error instanceof Error ? error.message : String(error)} session=${session ?? "unattributed"}`
53682
+ `model proxy: locking the frame of a call it did not forward (${reason3}) failed: ${error instanceof Error ? error.message : String(error)} session=${session ?? "unattributed"}`
53444
53683
  );
53445
53684
  };
53446
53685
  try {
@@ -53856,7 +54095,7 @@ function createModelProxy(deps) {
53856
54095
  void onSessionQueue(deps.exclusive, record, land).catch(
53857
54096
  (error) => {
53858
54097
  deps.log(
53859
- `model proxy: sealing a cache keep-alive's frame failed: ${error instanceof Error ? error.message : String(error)} session=${sessionKey}`
54098
+ `model proxy: locking a cache keep-alive's frame failed: ${error instanceof Error ? error.message : String(error)} session=${sessionKey}`
53860
54099
  );
53861
54100
  }
53862
54101
  );
@@ -54229,7 +54468,7 @@ function createModelProxy(deps) {
54229
54468
  };
54230
54469
  const logLostFrame = (error) => {
54231
54470
  deps.log(
54232
- `model proxy: sealing the call's frame failed, the response the caller already has is unaffected: ${error instanceof Error ? error.message : String(error)} session=${sessionKey}`
54471
+ `model proxy: locking the call's frame failed, the response the caller already has is unaffected: ${error instanceof Error ? error.message : String(error)} session=${sessionKey}`
54233
54472
  );
54234
54473
  };
54235
54474
  const afterLanding = (landed, errorClass2) => {
@@ -56397,7 +56636,7 @@ function createSessionHeads(deps) {
56397
56636
  text5 = await response.text();
56398
56637
  } catch (error) {
56399
56638
  deps.log(
56400
- `backfill pre-flight: the control plane did not answer (${error instanceof Error ? error.message : String(error)}); the pass seals nothing it cannot check`
56639
+ `backfill pre-flight: the control plane did not answer (${error instanceof Error ? error.message : String(error)}); the pass locks nothing it cannot check`
56401
56640
  );
56402
56641
  return void 0;
56403
56642
  } finally {
@@ -56405,7 +56644,7 @@ function createSessionHeads(deps) {
56405
56644
  }
56406
56645
  if (status2 < 200 || status2 >= 300) {
56407
56646
  deps.log(
56408
- `backfill pre-flight: the control plane answered ${status2}; the pass seals nothing it cannot check`
56647
+ `backfill pre-flight: the control plane answered ${status2}; the pass locks nothing it cannot check`
56409
56648
  );
56410
56649
  return void 0;
56411
56650
  }
@@ -56414,7 +56653,7 @@ function createSessionHeads(deps) {
56414
56653
  parsed2 = answerSchema.parse(JSON.parse(text5));
56415
56654
  } catch {
56416
56655
  deps.log(
56417
- "backfill pre-flight: the control plane's answer did not parse; the pass seals nothing it cannot check"
56656
+ "backfill pre-flight: the control plane's answer did not parse; the pass locks nothing it cannot check"
56418
56657
  );
56419
56658
  return void 0;
56420
56659
  }
@@ -56871,7 +57110,7 @@ async function initializeDaemon(options, server, port, ready, clock2) {
56871
57110
  const sealedState = parseSealedState(
56872
57111
  readJsonStateFile(
56873
57112
  paths.daemonSealedState,
56874
- (movedTo) => logSetAside("daemon sealed state", movedTo)
57113
+ (movedTo) => logSetAside("daemon state of locked sessions", movedTo)
56875
57114
  )
56876
57115
  );
56877
57116
  let reconcileMs = 0;
@@ -58087,7 +58326,7 @@ async function initializeDaemon(options, server, port, ready, clock2) {
58087
58326
  }
58088
58327
  } catch (error) {
58089
58328
  log(
58090
- `pending session ends unavailable: ${error instanceof Error ? error.message : String(error)}; those sessions are not sealed at this start. Check ${pendingEndsPath}`
58329
+ `pending session ends unavailable: ${error instanceof Error ? error.message : String(error)}; those sessions are not locked at this start. Check ${pendingEndsPath}`
58091
58330
  );
58092
58331
  }
58093
58332
  const persistPendingEnds = () => writeSensitiveFileAtomic(
@@ -58428,7 +58667,7 @@ async function initializeDaemon(options, server, port, ready, clock2) {
58428
58667
  if (key !== void 0) forgetHookId(session, key);
58429
58668
  }
58430
58669
  log(
58431
- `session end for ${uuid} conflicts with the WAL at ${conflict.sessionUuid}:${conflict.seq}; its sealed terminal is in quarantine/${name}, and the end is sealed again on the chain the WAL holds`
58670
+ `session end for ${uuid} conflicts with the WAL at ${conflict.sessionUuid}:${conflict.seq}; its locked end event is in quarantine/${name}, and the end is locked again on the chain the WAL holds`
58432
58671
  );
58433
58672
  }
58434
58673
  async function warmTerminalIndexes(sessionUuid2) {
@@ -59157,7 +59396,9 @@ async function initializeDaemon(options, server, port, ready, clock2) {
59157
59396
  return;
59158
59397
  }
59159
59398
  for (const refusal of session.recorder.takeOtelRefusals())
59160
- log(`OTel record not sealed for session ${sessionId}: ${refusal}`);
59399
+ log(
59400
+ `OTel record not locked into the chain for session ${sessionId}: ${refusal}`
59401
+ );
59161
59402
  }
59162
59403
  const api = {
59163
59404
  runContained: contained.run,
@@ -59598,7 +59839,7 @@ async function initializeDaemon(options, server, port, ready, clock2) {
59598
59839
  for (const session of registry2.list()) {
59599
59840
  for (const repair of session.recorder.takeSealRepairs()) {
59600
59841
  log(
59601
- `recorder sealed an event no path returned; written anyway: ${repair}`
59842
+ `recorder locked an event no path returned; written anyway: ${repair}`
59602
59843
  );
59603
59844
  }
59604
59845
  }
@@ -59872,6 +60113,28 @@ async function initializeDaemon(options, server, port, ready, clock2) {
59872
60113
  fetch: options.fetch ?? globalThis.fetch,
59873
60114
  log
59874
60115
  }),
60116
+ // What the API stored survives a restart, so a restart sends only new
60117
+ // and changed memories rather than every one on the machine (#7159).
60118
+ storage: fileStateStorage(
60119
+ paths.memorySent,
60120
+ (movedTo) => log(
60121
+ movedTo === void 0 ? "memory reader: the sent record did not parse and could not be moved aside; every memory is sent again" : `memory reader: the sent record did not parse; moved it to ${movedTo}, and every memory is sent again`
60122
+ )
60123
+ ),
60124
+ log,
60125
+ // A 429 is waited out within the scan. A stop ends the wait at once.
60126
+ wait: (ms) => new Promise((resolve28) => {
60127
+ if (stopping.signal.aborted) return resolve28(false);
60128
+ const done = (passed) => {
60129
+ clearTimeout(timer2);
60130
+ stopping.signal.removeEventListener("abort", onAbort);
60131
+ resolve28(passed);
60132
+ };
60133
+ const onAbort = () => done(false);
60134
+ const timer2 = setTimeout(() => done(true), ms);
60135
+ timer2.unref();
60136
+ stopping.signal.addEventListener("abort", onAbort, { once: true });
60137
+ }),
59875
60138
  harnesses: memoryLocations,
59876
60139
  scope: () => memoryScope.forScan(),
59877
60140
  // Codex's store follows `CODEX_HOME`. Only the agent that enrolls
@@ -59908,9 +60171,20 @@ async function initializeDaemon(options, server, port, ready, clock2) {
59908
60171
  const stella = stopped2 ? void 0 : await stellaMemories?.scan();
59909
60172
  const scans = [...result2.scans ?? [], ...stella?.scans ?? []];
59910
60173
  return { scans, counts: result2.counts };
59911
- }).then(
59912
- (result2) => stopped2 ? void 0 : memoryUses?.report(result2.scans, result2.counts)
59913
- ).catch((error) => {
60174
+ }).then(async (result2) => {
60175
+ if (stopped2 || memoryUses === void 0) return;
60176
+ const report = await memoryUses.report(result2.scans, result2.counts);
60177
+ if (report.missing.length === 0) return;
60178
+ log(
60179
+ `memory scan: the control plane holds no memory for ${report.missing.length} scanned files; they are sent again at the next scan`
60180
+ );
60181
+ memoryReader.resend(
60182
+ report.missing.filter((memory) => memory.harness !== "stella")
60183
+ );
60184
+ stellaMemories?.resend(
60185
+ report.missing.filter((memory) => memory.harness === "stella").map((memory) => memory.path)
60186
+ );
60187
+ }).catch((error) => {
59914
60188
  log(
59915
60189
  `memory scan failed: ${error instanceof Error ? error.message : String(error)}`
59916
60190
  );
@@ -59995,7 +60269,7 @@ async function initializeDaemon(options, server, port, ready, clock2) {
59995
60269
  });
59996
60270
  if (!await settleWithin(sealed, timers.stopQueueMs))
59997
60271
  log(
59998
- `stop: a task held the queue for ${timers.stopQueueMs} ms; the host chain seals when it finishes`
60272
+ `stop: a task held the queue for ${timers.stopQueueMs} ms; the host chain locks when it finishes`
59999
60273
  );
60000
60274
  if (!await settleWithin(shipper.drain(), timers.stopDrainMs))
60001
60275
  log(
@@ -64384,7 +64658,8 @@ var init_esm = __esm({
64384
64658
  });
64385
64659
 
64386
64660
  // ../../packages/tacho/src/collector/run.ts
64387
- import { readFileSync as readFileSync25, unlinkSync as unlinkSync15 } from "node:fs";
64661
+ import { readFileSync as readFileSync25, realpathSync as realpathSync7, statSync as statSync17, unlinkSync as unlinkSync15 } from "node:fs";
64662
+ import { dirname as dirname29, join as join53 } from "node:path";
64388
64663
  function stopWithin(stop, graceMs, exit, log) {
64389
64664
  const timer = setTimeout(() => {
64390
64665
  log(`tachod: stop did not finish within ${graceMs} ms, exiting
@@ -64446,6 +64721,87 @@ function writeDaemonPid(path2, now = /* @__PURE__ */ new Date(), execPath = proc
64446
64721
  420
64447
64722
  );
64448
64723
  }
64724
+ function installedCliVersion(entry2 = process.argv[1], read2 = (path2) => readFileSync25(path2, "utf8"), realpath3 = realpathSync7) {
64725
+ if (entry2 === void 0) return void 0;
64726
+ let dir;
64727
+ try {
64728
+ dir = dirname29(realpath3(entry2));
64729
+ } catch {
64730
+ return void 0;
64731
+ }
64732
+ for (let depth = 0; depth < CLI_PACKAGE_DEPTH_MAX; depth += 1) {
64733
+ try {
64734
+ const pkg = JSON.parse(read2(join53(dir, "package.json")));
64735
+ if (pkg.name === "@oxagen/cli")
64736
+ return typeof pkg.version === "string" ? pkg.version : void 0;
64737
+ } catch {
64738
+ }
64739
+ const parent = dirname29(dir);
64740
+ if (parent === dir) return void 0;
64741
+ dir = parent;
64742
+ }
64743
+ return void 0;
64744
+ }
64745
+ function processProbe() {
64746
+ return {
64747
+ entry: process.argv[1],
64748
+ native: isNativeBuild(),
64749
+ execPath: process.execPath,
64750
+ platform: process.platform,
64751
+ read: (path2) => readFileSync25(path2, "utf8"),
64752
+ realpath: realpathSync7,
64753
+ stat: statSync17,
64754
+ exists: (path2) => {
64755
+ try {
64756
+ statSync17(path2);
64757
+ return true;
64758
+ } catch {
64759
+ return false;
64760
+ }
64761
+ }
64762
+ };
64763
+ }
64764
+ function installedIdentity(probe = processProbe()) {
64765
+ if (!probe.native)
64766
+ return installedCliVersion(probe.entry, probe.read, probe.realpath);
64767
+ try {
64768
+ const real = probe.realpath(
64769
+ stableExecutablePath(probe.execPath, probe.platform, probe.exists)
64770
+ );
64771
+ const info = probe.stat(real);
64772
+ return `${real} (${info.size} bytes, changed ${new Date(info.mtimeMs).toISOString()})`;
64773
+ } catch {
64774
+ return void 0;
64775
+ }
64776
+ }
64777
+ function watchInstalledVersion(options) {
64778
+ const atStart = options.installed();
64779
+ let seen;
64780
+ let done = false;
64781
+ const set = options.setInterval ?? setInterval;
64782
+ const clear = options.clearInterval ?? ((handle2) => clearInterval(handle2));
64783
+ const handle = set(() => {
64784
+ if (done) return;
64785
+ const now = options.installed();
64786
+ const changed = now !== void 0 && now !== options.running && now !== atStart;
64787
+ if (!changed) {
64788
+ seen = void 0;
64789
+ return;
64790
+ }
64791
+ if (seen !== now) {
64792
+ seen = now;
64793
+ return;
64794
+ }
64795
+ done = true;
64796
+ clear(handle);
64797
+ options.restart(now);
64798
+ }, options.everyMs ?? VERSION_CHECK_MS);
64799
+ handle.unref?.();
64800
+ return () => {
64801
+ done = true;
64802
+ clear(handle);
64803
+ };
64804
+ }
64449
64805
  function ownProcStart() {
64450
64806
  if (process.platform !== "linux") return void 0;
64451
64807
  return readProcessStarts([process.pid], void 0, "linux")?.get(process.pid);
@@ -64567,6 +64923,17 @@ async function runDaemonProcess(options = {}) {
64567
64923
  releaseDaemonPid(paths.pid, previousPid);
64568
64924
  throw error;
64569
64925
  }
64926
+ watchInstalledVersion({
64927
+ running: TACHO_VERSION,
64928
+ installed: () => installedIdentity(),
64929
+ restart: (installed) => {
64930
+ log(
64931
+ `tachod: this daemon runs ${TACHO_VERSION} and the CLI installed under it is now ${installed}; restarting so the service manager starts the new one
64932
+ `
64933
+ );
64934
+ stop("CLI update");
64935
+ }
64936
+ });
64570
64937
  if (options.started !== void 0) {
64571
64938
  try {
64572
64939
  await options.started(
@@ -64583,7 +64950,7 @@ async function runDaemonProcess(options = {}) {
64583
64950
  }
64584
64951
  await new Promise(() => void 0);
64585
64952
  }
64586
- var STOP_GRACE_MS2;
64953
+ var STOP_GRACE_MS2, VERSION_CHECK_MS, CLI_PACKAGE_DEPTH_MAX;
64587
64954
  var init_run2 = __esm({
64588
64955
  "../../packages/tacho/src/collector/run.ts"() {
64589
64956
  "use strict";
@@ -64591,8 +64958,12 @@ var init_run2 = __esm({
64591
64958
  init_fs();
64592
64959
  init_paths();
64593
64960
  init_process_scan();
64961
+ init_deps();
64962
+ init_version();
64594
64963
  init_daemon();
64595
64964
  STOP_GRACE_MS2 = 5e3;
64965
+ VERSION_CHECK_MS = 10 * 6e4;
64966
+ CLI_PACKAGE_DEPTH_MAX = 6;
64596
64967
  }
64597
64968
  });
64598
64969
 
@@ -64605,21 +64976,21 @@ import {
64605
64976
  mkdirSync as mkdirSync9,
64606
64977
  openSync as openSync9,
64607
64978
  readSync as readSync5,
64608
- realpathSync as realpathSync7,
64979
+ realpathSync as realpathSync8,
64609
64980
  writeFileSync as writeFileSync6
64610
64981
  } from "node:fs";
64611
- import { dirname as dirname29, join as join53, resolve as resolve20 } from "node:path";
64982
+ import { dirname as dirname30, join as join54, resolve as resolve20 } from "node:path";
64612
64983
  function bundlePath(root, relative12, create2 = false) {
64613
64984
  const absolute = resolve20(root);
64614
64985
  if (create2) mkdirSync9(absolute, { recursive: true, mode: 448 });
64615
64986
  if (lstatSync10(absolute).isSymbolicLink() || !lstatSync10(absolute).isDirectory()) {
64616
64987
  arpFail(`The bundle root ${absolute} must be a directory, not a symlink.`);
64617
64988
  }
64618
- const base2 = realpathSync7(absolute);
64989
+ const base2 = realpathSync8(absolute);
64619
64990
  let current = base2;
64620
64991
  const parts = relative12.split("/");
64621
64992
  for (let i2 = 0; i2 < parts.length; i2++) {
64622
- current = join53(current, parts[i2]);
64993
+ current = join54(current, parts[i2]);
64623
64994
  try {
64624
64995
  const stat7 = lstatSync10(current);
64625
64996
  if (stat7.isSymbolicLink() || i2 < parts.length - 1 && !stat7.isDirectory()) {
@@ -64633,7 +65004,7 @@ function bundlePath(root, relative12, create2 = false) {
64633
65004
  else if (i2 < parts.length - 1) throw error;
64634
65005
  }
64635
65006
  }
64636
- if (realpathSync7(dirname29(current)) !== dirname29(current)) {
65007
+ if (realpathSync8(dirname30(current)) !== dirname30(current)) {
64637
65008
  arpFail(`The bundle directory changed while ${relative12} was read.`);
64638
65009
  }
64639
65010
  return current;
@@ -64651,7 +65022,8 @@ function readBounded(root, relative12, limit = ARP_MAX_BLOB_BYTES) {
64651
65022
  let offset = 0;
64652
65023
  while (offset < bytes.length) {
64653
65024
  const count12 = readSync5(fd2, bytes, offset, bytes.length - offset, offset);
64654
- if (!count12) arpFail(`The bundle file ${relative12} changed while it was read.`);
65025
+ if (!count12)
65026
+ arpFail(`The bundle file ${relative12} changed while it was read.`);
64655
65027
  offset += count12;
64656
65028
  }
64657
65029
  if (readSync5(fd2, Buffer.alloc(1), 0, 1, offset) !== 0)
@@ -64696,7 +65068,7 @@ function readBlob(root, ref) {
64696
65068
  const bytes = readBounded(root, blobPath(ref), ref.bytes);
64697
65069
  if (bytes.length !== ref.bytes || digestBytes(bytes) !== ref.digest) {
64698
65070
  arpFail(
64699
- `Blob ${ref.digest} failed its integrity check: its bytes do not match its digest and size (${ref.bytes} bytes).`
65071
+ `Blob ${ref.digest} failed its integrity check: its bytes do not match its hash and size (${ref.bytes} bytes).`
64700
65072
  );
64701
65073
  }
64702
65074
  return bytes;
@@ -64704,12 +65076,14 @@ function readBlob(root, ref) {
64704
65076
  function controlJson(bytes, name) {
64705
65077
  const value = JSON.parse(bytes.toString("utf8"));
64706
65078
  if (!Buffer.from(jcs(value)).equals(bytes))
64707
- arpFail(`The ${name} must use canonical JSON.`);
65079
+ arpFail(`The ${name} must use JSON in one standard form.`);
64708
65080
  function check2(item, depth) {
64709
65081
  if (depth > MAX_CONTROL_DEPTH)
64710
65082
  arpFail(`The ${name} nests deeper than ${MAX_CONTROL_DEPTH} levels.`);
64711
65083
  if (typeof item === "number" && !Number.isSafeInteger(item))
64712
- arpFail(`The ${name} holds ${item}, and its numbers must be safe integers.`);
65084
+ arpFail(
65085
+ `The ${name} holds ${item}, and its numbers must be safe integers.`
65086
+ );
64713
65087
  if (typeof item === "string" && /[\ud800-\udfff]/u.test(item))
64714
65088
  arpFail(`The ${name} contains an invalid Unicode string.`);
64715
65089
  if (item && typeof item === "object") {
@@ -64732,7 +65106,7 @@ function parseControl(schema, bytes, name) {
64732
65106
  function writeCheckpoint(root, checkpoint, key) {
64733
65107
  const parsed2 = arpCheckpointSchema.parse(checkpoint);
64734
65108
  const bytes = Buffer.from(jcs(parsed2));
64735
- controlJson(bytes, "checkpoint");
65109
+ controlJson(bytes, "save point");
64736
65110
  const subjectDigest = digestBytes(bytes);
64737
65111
  const attestation = {
64738
65112
  schema: "arp.attestation/0.1",
@@ -64858,16 +65232,16 @@ function verifyBundle2(root, trustedPublicKey) {
64858
65232
  const checkpoint = parseControl(
64859
65233
  arpCheckpointSchema,
64860
65234
  checkpointBytes,
64861
- "checkpoint"
65235
+ "save point"
64862
65236
  );
64863
65237
  if (checkpoint.gaps.some((gap) => gap.required) || checkpoint.effects.some((effect) => effect.status === "unknown")) {
64864
- arpFail("The checkpoint has required gaps or unresolved effects.");
65238
+ arpFail("The save point has required gaps or unresolved effects.");
64865
65239
  }
64866
65240
  const checkpointDigest = digestBytes(checkpointBytes);
64867
65241
  const attestation = parseControl(
64868
65242
  attestationSchema,
64869
65243
  readBounded(root, "checkpoint.attestation.json", 4096),
64870
- "checkpoint attestation"
65244
+ "save point lock"
64871
65245
  );
64872
65246
  if (checkpoint.issuer !== deviceKeyFingerprint(trustedPublicKey) || attestation.subject_digest !== checkpointDigest || attestation.key_id !== deviceKeyFingerprint(trustedPublicKey) || !verifyDeviceSignature(
64873
65247
  trustedPublicKey,
@@ -64875,7 +65249,7 @@ function verifyBundle2(root, trustedPublicKey) {
64875
65249
  ${checkpointDigest}`,
64876
65250
  attestation.signature
64877
65251
  )) {
64878
- arpFail("The checkpoint signature does not match the trusted key.");
65252
+ arpFail("The save point's lock does not match the trusted key.");
64879
65253
  }
64880
65254
  let total2 = 0;
64881
65255
  const seen = /* @__PURE__ */ new Map();
@@ -64961,7 +65335,7 @@ ${checkpointDigest}`,
64961
65335
  const evidence = JSON.parse(evidenceBytes.toString("utf8"));
64962
65336
  if (!Buffer.from(jcs(evidence)).equals(evidenceBytes)) {
64963
65337
  arpFail(
64964
- "The evidence array must use canonical JSON without changing native events."
65338
+ "The evidence array must use JSON in one standard form without changing native events."
64965
65339
  );
64966
65340
  }
64967
65341
  if (!Array.isArray(evidence) || evidence.length > MAX_EVIDENCE_EVENTS)
@@ -65056,7 +65430,7 @@ function readHandoffFrames(bytes) {
65056
65430
  }
65057
65431
  if (frame2.content_digest !== digestBytes(frame2.content) || frame2.token_cost !== budgetTokens(frame2.content)) {
65058
65432
  arpFail(
65059
- `Context frame ${frame2.id} has an invalid CGP content digest or token cost.`
65433
+ `Context frame ${frame2.id} has an invalid CGP content hash or token cost.`
65060
65434
  );
65061
65435
  }
65062
65436
  }
@@ -65464,20 +65838,20 @@ function checkDeterministicComposition(journal) {
65464
65838
  });
65465
65839
  } else if (first.digest !== event.composition_digest) {
65466
65840
  violations.push(
65467
- `the frame set rendered at seq ${event.seq} is identical to seq ${first.seq} but composed to a different digest: an unchanged set must render byte-identically (section 1)`
65841
+ `the frame set rendered at seq ${event.seq} is identical to seq ${first.seq} but composed to a different hash: an unchanged set must render byte-identically (section 1)`
65468
65842
  );
65469
65843
  }
65470
65844
  }
65471
65845
  if (digested === 0) {
65472
65846
  return skip(
65473
65847
  CHECK_COMPOSITION,
65474
- "no composition digests recorded: prefix stability not exercised by this journal"
65848
+ "no composition hashes recorded: prefix stability not exercised by this journal"
65475
65849
  );
65476
65850
  }
65477
65851
  return fromViolations(
65478
65852
  CHECK_COMPOSITION,
65479
65853
  violations,
65480
- `${digested} digest-carrying prompt(s); identical frame sets composed identically`
65854
+ `${digested} hash-carrying prompt(s); identical frame sets composed identically`
65481
65855
  );
65482
65856
  }
65483
65857
  function checkEffectExactlyOnce(journal) {
@@ -65576,11 +65950,11 @@ import {
65576
65950
  mkdirSync as mkdirSync10,
65577
65951
  openSync as openSync10,
65578
65952
  readSync as readSync6,
65579
- realpathSync as realpathSync8,
65953
+ realpathSync as realpathSync9,
65580
65954
  rmSync as rmSync12,
65581
65955
  writeFileSync as writeFileSync7
65582
65956
  } from "node:fs";
65583
- import { dirname as dirname30, isAbsolute as isAbsolute15, join as join54, relative as relative6, resolve as resolve21, sep as sep8 } from "node:path";
65957
+ import { dirname as dirname31, isAbsolute as isAbsolute15, join as join55, relative as relative6, resolve as resolve21, sep as sep8 } from "node:path";
65584
65958
  function outsideProfile(path2) {
65585
65959
  return HARNESS_CONFIG_PATH.test(path2) || CREDENTIAL_PATH.test(path2);
65586
65960
  }
@@ -65595,9 +65969,7 @@ function readRegular(label2, path2, limit) {
65595
65969
  try {
65596
65970
  const before = fstatSync3(fd2);
65597
65971
  if (!before.isFile() || before.size > limit)
65598
- arpFail(
65599
- `${label2} ${path2} is not a regular file of at most ${limit} bytes.`
65600
- );
65972
+ arpFail(`${label2} ${path2} is not a regular file of at most ${limit} bytes.`);
65601
65973
  const bytes = Buffer.alloc(before.size);
65602
65974
  let offset = 0;
65603
65975
  while (offset < bytes.length) {
@@ -65636,9 +66008,9 @@ function within2(root, path2) {
65636
66008
  }
65637
66009
  function newPath(path2) {
65638
66010
  const full = resolve21(path2);
65639
- return join54(
65640
- realpathSync8(dirname30(full)),
65641
- full.slice(dirname30(full).length + 1)
66011
+ return join55(
66012
+ realpathSync9(dirname31(full)),
66013
+ full.slice(dirname31(full).length + 1)
65642
66014
  );
65643
66015
  }
65644
66016
  function sourcePath(root, path2) {
@@ -65650,7 +66022,7 @@ function sourcePath(root, path2) {
65650
66022
  }
65651
66023
  let current = root;
65652
66024
  for (const part2 of path2.split("/")) {
65653
- current = join54(current, part2);
66025
+ current = join55(current, part2);
65654
66026
  if (lstatSync11(current).isSymbolicLink())
65655
66027
  arpFail(
65656
66028
  `${path2} is a symlink or passes through one. Symlinks require a resource adapter.`
@@ -65701,15 +66073,15 @@ function readBrief(path2) {
65701
66073
  function captureCheckpoint(options) {
65702
66074
  if (!options.attestBoundary)
65703
66075
  arpFail(
65704
- "Pass --attest-boundary to attest that the stopped workspace matches the brief's evidence boundary."
66076
+ "Pass --attest-boundary to confirm that the stopped workspace matches the brief's evidence boundary."
65705
66077
  );
65706
- const root = realpathSync8(options.workspace);
66078
+ const root = realpathSync9(options.workspace);
65707
66079
  if (!lstatSync11(root).isDirectory())
65708
66080
  arpFail(`The workspace ${root} is not a directory.`);
65709
66081
  const out = newPath(options.out);
65710
66082
  if (within2(root, out))
65711
66083
  arpFail(
65712
- `Write the checkpoint outside its source workspace; ${out} is inside ${root}.`
66084
+ `Write the save point outside its source workspace; ${out} is inside ${root}.`
65713
66085
  );
65714
66086
  const brief = readBrief(options.briefFile);
65715
66087
  const evidenceBytes = readRegular(
@@ -65865,7 +66237,7 @@ function captureCheckpoint(options) {
65865
66237
  function prepareCheckpoint(options) {
65866
66238
  const harness = external_exports.enum(["codex", "claude-code", "cursor", "stella"]).parse(options.harness);
65867
66239
  const verified = verifyBundle2(options.bundle, options.publicKey);
65868
- const bundle2 = realpathSync8(options.bundle);
66240
+ const bundle2 = realpathSync9(options.bundle);
65869
66241
  const { checkpoint, workspace, checkpointDigest, events } = verified;
65870
66242
  const blob = (ref) => verified.blobs.get(ref.digest) ?? arpFail(`Blob ${ref.digest} was not read during verification.`);
65871
66243
  const traceReport = runOracles(projectToTrace(events));
@@ -65878,15 +66250,15 @@ function prepareCheckpoint(options) {
65878
66250
  );
65879
66251
  const taskBytes = blob(checkpoint.task);
65880
66252
  const contextBytes = blob(checkpoint.context);
65881
- rejectSecrets("The checkpoint's task", taskBytes);
65882
- rejectSecrets("The checkpoint's context", contextBytes);
66253
+ rejectSecrets("The save point's task", taskBytes);
66254
+ rejectSecrets("The save point's context", contextBytes);
65883
66255
  const task = external_exports.object({ request: external_exports.string().min(1).max(64e3) }).strict().safeParse(JSON.parse(taskBytes.toString("utf8")));
65884
66256
  if (!task.success)
65885
- arpFail(`The checkpoint's task is not valid: ${zodIssues(task.error)}.`);
66257
+ arpFail(`The save point's task is not valid: ${zodIssues(task.error)}.`);
65886
66258
  const frames = readHandoffFrames(contextBytes);
65887
66259
  if (!sameJson(blob(checkpoint.environment), CAPTURED_ENVIRONMENT) || !sameJson(blob(checkpoint.authority), CAPTURED_AUTHORITY) || !sameJson(blob(checkpoint.tools), CAPTURED_TOOLS)) {
65888
66260
  arpFail(
65889
- "The checkpoint needs an environment, tool, or authority adapter not supported here."
66261
+ "The save point needs an environment, tool, or authority adapter not supported here."
65890
66262
  );
65891
66263
  }
65892
66264
  const unsupported = checkpoint.gaps.filter(
@@ -65894,7 +66266,7 @@ function prepareCheckpoint(options) {
65894
66266
  );
65895
66267
  if (workspace.repositories.length > 0 || unsupported.length > 0) {
65896
66268
  arpFail(
65897
- `The checkpoint requires a repository or gap adapter not supported here${unsupported.length > 0 ? ` (gaps: ${unsupported.map((gap) => gap.code).join(", ")})` : ""}.`
66269
+ `The save point requires a repository or gap adapter not supported here${unsupported.length > 0 ? ` (gaps: ${unsupported.map((gap) => gap.code).join(", ")})` : ""}.`
65898
66270
  );
65899
66271
  }
65900
66272
  const restore = workspace.entries.map((entry2) => {
@@ -65917,23 +66289,23 @@ function prepareCheckpoint(options) {
65917
66289
  });
65918
66290
  mkdirSync10(destination, { mode: 448 });
65919
66291
  try {
65920
- const restored = join54(destination, "workspace");
66292
+ const restored = join55(destination, "workspace");
65921
66293
  mkdirSync10(restored, { mode: 448 });
65922
66294
  for (const item of restore) {
65923
- const path2 = join54(restored, item.path);
66295
+ const path2 = join55(restored, item.path);
65924
66296
  if (item.kind === "directory")
65925
66297
  mkdirSync10(path2, { recursive: true, mode: 448 });
65926
66298
  else {
65927
- mkdirSync10(dirname30(path2), { recursive: true, mode: 448 });
66299
+ mkdirSync10(dirname31(path2), { recursive: true, mode: 448 });
65928
66300
  writeFileSync7(path2, item.bytes, {
65929
66301
  flag: "wx",
65930
66302
  mode: item.executable ? 448 : 384
65931
66303
  });
65932
66304
  }
65933
66305
  }
65934
- const promptDir = join54(restored, ".arp");
66306
+ const promptDir = join55(restored, ".arp");
65935
66307
  mkdirSync10(promptDir, { mode: 448 });
65936
- const promptFile = join54(promptDir, "handoff.json");
66308
+ const promptFile = join55(promptDir, "handoff.json");
65937
66309
  const prompt = {
65938
66310
  checkpoint_digest: checkpointDigest,
65939
66311
  task: task.data.request,
@@ -65950,7 +66322,7 @@ function prepareCheckpoint(options) {
65950
66322
  flag: "wx",
65951
66323
  mode: 384
65952
66324
  });
65953
- const reportPath = join54(destination, "report.json");
66325
+ const reportPath = join55(destination, "report.json");
65954
66326
  writeFileSync7(
65955
66327
  reportPath,
65956
66328
  jcs(
@@ -66065,7 +66437,7 @@ var init_transfer = __esm({
66065
66437
 
66066
66438
  // ../../packages/tacho/src/cli/arp.ts
66067
66439
  function addArpCommands(program2, deps = defaultCliDeps()) {
66068
- const arp = program2.command("arp").description("Capture and prepare local Agent Run Protocol checkpoints");
66440
+ const arp = program2.command("arp").description("Capture and prepare local Agent Run Protocol save points");
66069
66441
  async function report(operation, next) {
66070
66442
  try {
66071
66443
  deps.out(JSON.stringify(await operation()));
@@ -66075,12 +66447,12 @@ function addArpCommands(program2, deps = defaultCliDeps()) {
66075
66447
  process.exitCode = 1;
66076
66448
  }
66077
66449
  }
66078
- arp.command("capture").description("Sign selected files and a brief at a stopped turn boundary").requiredOption("--workspace <directory>", "Stopped source workspace").requiredOption("--evidence <file>", "Tacho export ending at turn_end").requiredOption(
66450
+ arp.command("capture").description("Lock selected files and a brief at a stopped turn boundary").requiredOption("--workspace <directory>", "Stopped source workspace").requiredOption("--evidence <file>", "Tacho export ending at turn_end").requiredOption(
66079
66451
  "--brief <file>",
66080
66452
  "Transfer brief and explicit file selection"
66081
- ).requiredOption("--out <directory>", "New checkpoint directory").requiredOption("--key <file>", "Checkpoint signing key file").requiredOption(
66453
+ ).requiredOption("--out <directory>", "New save point directory").requiredOption("--key <file>", "Key file that locks the save point").requiredOption(
66082
66454
  "--attest-boundary",
66083
- "Attest that the stopped workspace matches the evidence boundary"
66455
+ "Confirm that the stopped workspace matches the evidence boundary"
66084
66456
  ).action(
66085
66457
  async (opts) => {
66086
66458
  await report(
@@ -66096,22 +66468,27 @@ function addArpCommands(program2, deps = defaultCliDeps()) {
66096
66468
  );
66097
66469
  }
66098
66470
  );
66099
- arp.command("verify").description("Check checkpoint integrity against a pinned public key").requiredOption("--bundle <directory>", "Checkpoint directory").requiredOption("--public-key <key>", "Trusted checkpoint public key").action(async (opts) => {
66100
- await report(
66101
- async () => {
66102
- const verified = await verifyBundle2(opts.bundle, opts.publicKey);
66103
- return { checkpointDigest: verified.checkpointDigest };
66104
- },
66105
- "Check that --bundle names a checkpoint directory and that --public-key is the key the checkpoint was signed with. Run `oxagen arp verify --help` for each option."
66106
- );
66471
+ arp.command("verify").description(
66472
+ "Check that a save point is unchanged, using a pinned public key"
66473
+ ).requiredOption("--bundle <directory>", "Save point directory").requiredOption(
66474
+ "--public-key <key>",
66475
+ "Trusted public key for the save point"
66476
+ ).action(async (opts) => {
66477
+ await report(async () => {
66478
+ const verified = await verifyBundle2(opts.bundle, opts.publicKey);
66479
+ return { checkpointDigest: verified.checkpointDigest };
66480
+ }, "Check that --bundle names a save point directory and that --public-key matches the key that locked the save point. Run `oxagen arp verify --help` for each option.");
66107
66481
  });
66108
- arp.command("prepare").description("Restore selected files and write a prompt for a fresh run").requiredOption("--bundle <directory>", "Checkpoint directory").requiredOption("--destination <directory>", "New preparation directory").requiredOption("--public-key <key>", "Trusted checkpoint public key").addOption(
66482
+ arp.command("prepare").description("Restore selected files and write a prompt for a fresh run").requiredOption("--bundle <directory>", "Save point directory").requiredOption("--destination <directory>", "New preparation directory").requiredOption(
66483
+ "--public-key <key>",
66484
+ "Trusted public key for the save point"
66485
+ ).addOption(
66109
66486
  new Option("--harness <name>", "Destination harness").choices(["claude-code", "codex", "cursor", "stella"]).makeOptionMandatory()
66110
66487
  ).action(
66111
66488
  async (opts) => {
66112
66489
  await report(
66113
66490
  () => prepareCheckpoint(opts),
66114
- "Check that --bundle names a checkpoint directory, that --public-key is the key the checkpoint was signed with, and that --destination names a directory that does not exist yet. Run `oxagen arp prepare --help` for each option."
66491
+ "Check that --bundle names a save point directory, that --public-key matches the key that locked the save point, and that --destination names a directory that does not exist yet. Run `oxagen arp prepare --help` for each option."
66115
66492
  );
66116
66493
  }
66117
66494
  );
@@ -66642,8 +67019,8 @@ var init_package = __esm({
66642
67019
  "package.json"() {
66643
67020
  package_default = {
66644
67021
  name: "@oxagen/cli",
66645
- version: "3.0.0",
66646
- description: "Oxagen governance CLI \u2014 spend, lineage, grounding, credentials, and audit (agentic coding lives in the stella CLI)",
67022
+ version: "3.0.1-27",
67023
+ description: "Oxagen governance CLI: spend, source tracking, grounding, credentials, and audit (agentic coding lives in the stella CLI)",
66647
67024
  type: "module",
66648
67025
  main: "./dist/index.js",
66649
67026
  bin: {
@@ -66709,10 +67086,10 @@ var init_package = __esm({
66709
67086
 
66710
67087
  // src/lib/atomic-write.ts
66711
67088
  import { writeFileSync as writeFileSync8, renameSync as renameSync7, unlinkSync as unlinkSync16, existsSync as existsSync26 } from "node:fs";
66712
- import { dirname as dirname31, join as join55 } from "node:path";
67089
+ import { dirname as dirname32, join as join56 } from "node:path";
66713
67090
  function atomicWriteFileSync(path2, data, mode) {
66714
- const dir = dirname31(path2);
66715
- const tmp = join55(
67091
+ const dir = dirname32(path2);
67092
+ const tmp = join56(
66716
67093
  dir,
66717
67094
  `.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`
66718
67095
  );
@@ -66737,8 +67114,8 @@ var init_atomic_write = __esm({
66737
67114
 
66738
67115
  // src/lib/config.ts
66739
67116
  import { homedir as homedir9 } from "os";
66740
- import { join as join56 } from "path";
66741
- import { readFileSync as readFileSync27, mkdirSync as mkdirSync11, existsSync as existsSync27, statSync as statSync17 } from "fs";
67117
+ import { join as join57 } from "path";
67118
+ import { readFileSync as readFileSync27, mkdirSync as mkdirSync11, existsSync as existsSync27, statSync as statSync18 } from "fs";
66742
67119
  function getConfigDir() {
66743
67120
  return CONFIG_DIR;
66744
67121
  }
@@ -66768,7 +67145,7 @@ function parseConfig(raw) {
66768
67145
  function readConfig() {
66769
67146
  let identity;
66770
67147
  try {
66771
- const info = statSync17(CONFIG_FILE);
67148
+ const info = statSync18(CONFIG_FILE);
66772
67149
  identity = `${info.ino}:${info.size}:${info.mtimeMs}`;
66773
67150
  } catch {
66774
67151
  cached2 = void 0;
@@ -66824,8 +67201,8 @@ var CONFIG_DIR, CONFIG_FILE, STRING_FIELDS, TELEMETRY_FIELDS, cached2;
66824
67201
  var init_config = __esm({
66825
67202
  "src/lib/config.ts"() {
66826
67203
  init_atomic_write();
66827
- CONFIG_DIR = join56(homedir9(), ".config", "oxagen");
66828
- CONFIG_FILE = join56(CONFIG_DIR, "config.json");
67204
+ CONFIG_DIR = join57(homedir9(), ".config", "oxagen");
67205
+ CONFIG_FILE = join57(CONFIG_DIR, "config.json");
66829
67206
  STRING_FIELDS = [
66830
67207
  "token",
66831
67208
  "orgSlug",
@@ -66870,16 +67247,16 @@ import {
66870
67247
  writeFile as writeFile2
66871
67248
  } from "node:fs/promises";
66872
67249
  import { homedir as homedir10 } from "node:os";
66873
- import { join as join57 } from "node:path";
67250
+ import { join as join58 } from "node:path";
66874
67251
  function isDebugEnabled() {
66875
67252
  const v = process.env[DEBUG_ENV];
66876
67253
  return v === "1" || v === "true";
66877
67254
  }
66878
67255
  function logsDir() {
66879
- return join57(homedir10(), ".oxagen", "logs");
67256
+ return join58(homedir10(), ".oxagen", "logs");
66880
67257
  }
66881
67258
  function debugLogFile() {
66882
- return join57(logsDir(), "cli.output");
67259
+ return join58(logsDir(), "cli.output");
66883
67260
  }
66884
67261
  function sanitize(value, depth = 0) {
66885
67262
  if (value === null || value === void 0) return value;
@@ -67101,12 +67478,12 @@ function diagnosticHeaders(res) {
67101
67478
  }
67102
67479
  function httpErrorHint(status2, traceId) {
67103
67480
  if (status2 >= 500) {
67104
- return "Server-side error \u2014 the stack lives in the API's runtime logs, not here. " + (traceId ? `Look up request id "${traceId}" (its region prefix names the deployment): \`vercel logs <deployment-url>\` or the Vercel dashboard \u2192 Logs.` : "Check the API deployment's runtime logs.");
67481
+ return "Server-side error. The stack lives in the API's runtime logs, not here. " + (traceId ? `Look up request id "${traceId}" (its region prefix names the deployment): \`vercel logs <deployment-url>\` or the Vercel dashboard \u2192 Logs.` : "Check the API deployment's runtime logs.");
67105
67482
  }
67106
67483
  if (status2 === 401 || status2 === 403) {
67107
67484
  return "Auth/scope rejected. Re-check `oxagen login` or OXAGEN_API_TOKEN / OXAGEN_ORG_ID / OXAGEN_WORKSPACE_ID.";
67108
67485
  }
67109
- if (status2 === 429) return "Rate limited \u2014 honor the retry-after header.";
67486
+ if (status2 === 429) return "Rate limited. Honor the retry-after header.";
67110
67487
  return void 0;
67111
67488
  }
67112
67489
  async function buildHttpError(event, method, url, path2, res, startedAt, secret) {
@@ -68366,7 +68743,7 @@ function printProjection(opts, writer) {
68366
68743
  const factor = cheap.totalUsd > 0 ? (dear.totalUsd / cheap.totalUsd).toFixed(1) : "\u221E";
68367
68744
  out("");
68368
68745
  out(
68369
- ` cheapest: ${cheap.label} (${formatUsd(cheap.totalUsd)}) \u2014 ${factor}\xD7 cheaper than ${dear.label}.`
68746
+ ` cheapest: ${cheap.label} (${formatUsd(cheap.totalUsd)}), ${factor}\xD7 cheaper than ${dear.label}.`
68370
68747
  );
68371
68748
  }
68372
68749
  if (rows.some((r) => r.fallback))
@@ -69586,8 +69963,8 @@ function checkLine(check2) {
69586
69963
  async function contextRevert(proposalId, opts, writer = stdoutWriter) {
69587
69964
  const out = createOutput({ json: opts.json }, writer);
69588
69965
  if (!proposalId || !PROPOSAL_ID.test(proposalId)) {
69589
- writer.writeErr("error: name the merged proposal, such as prp_01k5ru4a");
69590
- writer.writeErr("usage: oxagen context revert <proposalId> [--json]");
69966
+ writer.writeErr("error: name the merged suggestion, such as prp_01k5ru4a");
69967
+ writer.writeErr("usage: oxagen context revert <suggestionId> [--json]");
69591
69968
  process.exitCode = 2;
69592
69969
  return;
69593
69970
  }
@@ -69723,7 +70100,7 @@ async function steeringFindings(opts = {}, writer = stdoutWriter) {
69723
70100
  if (index > 0) writer.write("");
69724
70101
  writer.write(`${repository.full_name} (${repository.provider})`);
69725
70102
  printTable(
69726
- ["FINDING", "KIND", "FILE", "RECORD", "PULL REQUEST", "PROPOSAL"],
70103
+ ["FINDING", "KIND", "FILE", "RECORD", "PULL REQUEST", "SUGGESTION"],
69727
70104
  repository.findings.map(findingRow),
69728
70105
  writer
69729
70106
  );
@@ -69738,7 +70115,7 @@ async function steeringFindings(opts = {}, writer = stdoutWriter) {
69738
70115
  );
69739
70116
  if (promotable) {
69740
70117
  writer.write(
69741
- "Promote a contradiction to a proposal with `oxagen steering promote <finding-id>`."
70118
+ "Promote a contradiction to a suggestion with `oxagen steering promote <finding-id>`."
69742
70119
  );
69743
70120
  }
69744
70121
  }
@@ -70556,9 +70933,9 @@ var init_git = __esm({
70556
70933
 
70557
70934
  // ../../packages/steering-freshness/src/cache.ts
70558
70935
  import { mkdir as mkdir4, readFile as readFile6, writeFile as writeFile4 } from "node:fs/promises";
70559
- import { dirname as dirname32, join as join58 } from "node:path";
70936
+ import { dirname as dirname33, join as join59 } from "node:path";
70560
70937
  function stampPath(gitCommonDir) {
70561
- return join58(gitCommonDir, "oxagen", "steering-freshness.json");
70938
+ return join59(gitCommonDir, "oxagen", "steering-freshness.json");
70562
70939
  }
70563
70940
  async function readFetchStamp(gitCommonDir, io = defaultIo) {
70564
70941
  try {
@@ -70579,7 +70956,7 @@ async function readFetchStamp(gitCommonDir, io = defaultIo) {
70579
70956
  async function writeFetchStamp(gitCommonDir, stamp, io = defaultIo) {
70580
70957
  const path2 = stampPath(gitCommonDir);
70581
70958
  try {
70582
- await io.mkdirp(dirname32(path2));
70959
+ await io.mkdirp(dirname33(path2));
70583
70960
  await io.write(path2, `${JSON.stringify(stamp)}
70584
70961
  `, "utf8");
70585
70962
  } catch {
@@ -70610,24 +70987,24 @@ var init_cache = __esm({
70610
70987
  // ../../packages/steering-freshness/src/hooks.ts
70611
70988
  import { mkdir as mkdir5, readFile as readFile7, writeFile as writeFile5 } from "node:fs/promises";
70612
70989
  import { homedir as homedir11 } from "node:os";
70613
- import { dirname as dirname33, join as join59 } from "node:path";
70990
+ import { dirname as dirname34, join as join60 } from "node:path";
70614
70991
  function hookCommand(harness) {
70615
70992
  return `oxagen steering gate --harness ${harness}`;
70616
70993
  }
70617
70994
  function hookConfigPath(projectRoot, harness, env = process.env, home = homedir11()) {
70618
70995
  switch (harness) {
70619
70996
  case "claude-code":
70620
- return join59(projectRoot, ".claude", "settings.json");
70997
+ return join60(projectRoot, ".claude", "settings.json");
70621
70998
  case "codex":
70622
- return join59(env["CODEX_HOME"] ?? join59(home, ".codex"), "hooks.json");
70999
+ return join60(env["CODEX_HOME"] ?? join60(home, ".codex"), "hooks.json");
70623
71000
  case "cursor":
70624
- return join59(home, ".cursor", "hooks.json");
71001
+ return join60(home, ".cursor", "hooks.json");
70625
71002
  case "stella":
70626
- return join59(env["STELLA_HOME"] ?? join59(home, ".stella"), "stella.toml");
71003
+ return join60(env["STELLA_HOME"] ?? join60(home, ".stella"), "stella.toml");
70627
71004
  }
70628
71005
  }
70629
71006
  function stellaJsonPath(env, home) {
70630
- return join59(env["STELLA_HOME"] ?? join59(home, ".stella"), "settings.json");
71007
+ return join60(env["STELLA_HOME"] ?? join60(home, ".stella"), "settings.json");
70631
71008
  }
70632
71009
  function isRecord8(v) {
70633
71010
  return v !== null && typeof v === "object" && !Array.isArray(v);
@@ -70714,7 +71091,7 @@ async function installJsonGroupHook(path2, harness, entry2, io) {
70714
71091
  };
70715
71092
  }
70716
71093
  const had = hasGroupHook(loaded.config);
70717
- await io.mkdirp(dirname33(path2));
71094
+ await io.mkdirp(dirname34(path2));
70718
71095
  await io.write(
70719
71096
  path2,
70720
71097
  `${JSON.stringify(withGroupHook(loaded.config, entry2), null, 2)}
@@ -70816,7 +71193,7 @@ async function installCursorHook(path2, io) {
70816
71193
  ];
70817
71194
  const next = { ...config, hooks };
70818
71195
  if (next.version === void 0) next.version = 1;
70819
- await io.mkdirp(dirname33(path2));
71196
+ await io.mkdirp(dirname34(path2));
70820
71197
  await io.write(path2, `${JSON.stringify(next, null, 2)}
70821
71198
  `, "utf8");
70822
71199
  return {
@@ -70999,7 +71376,7 @@ async function installStellaHook(projectRoot, io, env, home) {
70999
71376
  }
71000
71377
  const separator = base2.length === 0 ? "" : eol;
71001
71378
  const next = `${base2}${separator}${renderStellaBlock(eol)}`;
71002
- await io.mkdirp(dirname33(path2));
71379
+ await io.mkdirp(dirname34(path2));
71003
71380
  await io.write(path2, next, "utf8");
71004
71381
  return {
71005
71382
  harness: "stella",
@@ -71287,7 +71664,7 @@ var init_policy = __esm({
71287
71664
  // ../../packages/steering-freshness/src/settings.ts
71288
71665
  import { readFile as readFile8 } from "node:fs/promises";
71289
71666
  import { homedir as homedir12 } from "node:os";
71290
- import { join as join60 } from "node:path";
71667
+ import { join as join61 } from "node:path";
71291
71668
  async function readLayer(scope, path2, read2) {
71292
71669
  let text5;
71293
71670
  try {
@@ -71339,14 +71716,14 @@ function parseLayer(scope, path2, text5) {
71339
71716
  }
71340
71717
  async function loadSteeringSettings({
71341
71718
  projectRoot,
71342
- userSettingsPath = join60(homedir12(), USER_SETTINGS_RELATIVE),
71719
+ userSettingsPath = join61(homedir12(), USER_SETTINGS_RELATIVE),
71343
71720
  read: read2 = readFile8,
71344
71721
  workspacePolicy = null
71345
71722
  }) {
71346
71723
  const targets = [
71347
71724
  ["user", userSettingsPath],
71348
- ["project", join60(projectRoot, PROJECT_DIR_NAME, PROJECT_SETTINGS_FILE)],
71349
- ["local", join60(projectRoot, PROJECT_DIR_NAME, LOCAL_SETTINGS_FILE)]
71725
+ ["project", join61(projectRoot, PROJECT_DIR_NAME, PROJECT_SETTINGS_FILE)],
71726
+ ["local", join61(projectRoot, PROJECT_DIR_NAME, LOCAL_SETTINGS_FILE)]
71350
71727
  ];
71351
71728
  const layers = [];
71352
71729
  const warnings = [];
@@ -71409,7 +71786,7 @@ var init_settings = __esm({
71409
71786
  "use strict";
71410
71787
  init_git();
71411
71788
  init_policy();
71412
- USER_SETTINGS_RELATIVE = join60(
71789
+ USER_SETTINGS_RELATIVE = join61(
71413
71790
  ".config",
71414
71791
  "oxagen",
71415
71792
  "settings.json"
@@ -71422,7 +71799,7 @@ var init_settings = __esm({
71422
71799
 
71423
71800
  // ../../packages/steering-freshness/src/check.ts
71424
71801
  import { lstat as lstat4 } from "node:fs/promises";
71425
- import { isAbsolute as isAbsolute16, join as join61, resolve as resolve22 } from "node:path";
71802
+ import { isAbsolute as isAbsolute16, join as join62, resolve as resolve22 } from "node:path";
71426
71803
  function publishedCommits(platform) {
71427
71804
  if (platform.headCommits && platform.headCommits.length > 0)
71428
71805
  return platform.headCommits;
@@ -71759,7 +72136,7 @@ async function absentFromDisk(root, paths) {
71759
72136
  const flags = await Promise.all(
71760
72137
  paths.map(async (path2) => {
71761
72138
  try {
71762
- await lstat4(join61(root, path2));
72139
+ await lstat4(join62(root, path2));
71763
72140
  return false;
71764
72141
  } catch {
71765
72142
  return true;
@@ -71818,7 +72195,7 @@ var init_check = __esm({
71818
72195
  // ../../packages/steering-freshness/src/sync.ts
71819
72196
  import { mkdtemp, rm as rm3, writeFile as writeFile6 } from "node:fs/promises";
71820
72197
  import { tmpdir as tmpdir2 } from "node:os";
71821
- import { join as join62 } from "node:path";
72198
+ import { join as join63 } from "node:path";
71822
72199
  function refuse3(refusal, message) {
71823
72200
  return {
71824
72201
  applied: false,
@@ -71999,9 +72376,9 @@ async function syncSteering(opts) {
71999
72376
  };
72000
72377
  }
72001
72378
  async function commitPaths(ctx, message, paths) {
72002
- const dir = await mkdtemp(join62(tmpdir2(), "oxagen-steering-sync-"));
72379
+ const dir = await mkdtemp(join63(tmpdir2(), "oxagen-steering-sync-"));
72003
72380
  try {
72004
- const list2 = join62(dir, "pathspec");
72381
+ const list2 = join63(dir, "pathspec");
72005
72382
  await writeFile6(list2, `${paths.join("\0")}\0`, "utf8");
72006
72383
  await git3(
72007
72384
  ctx,
@@ -72432,6 +72809,8 @@ function parseLedgerFileName(name) {
72432
72809
  }
72433
72810
  function classifySteering(parts) {
72434
72811
  const name = parts[parts.length - 1];
72812
+ if (parts[1] === PEOPLE_DIR && PERSON_FOLDER.test(parts[2] ?? ""))
72813
+ return parts.length >= 5 && name.endsWith(".md") ? "person-record" : "unknown";
72435
72814
  if (parts[1] === "promotions") {
72436
72815
  return parts.length === 3 && parseLedgerFileName(name) ? "ledger" : "unknown";
72437
72816
  }
@@ -72486,11 +72865,11 @@ function recordLineageFromPath(path2) {
72486
72865
  const kind = classifySteeringRepoPath(path2);
72487
72866
  const parts = path2.split("/");
72488
72867
  if (kind === "skill-record") return parts[2];
72489
- if (kind === "record")
72868
+ if (kind === "record" || kind === "person-record")
72490
72869
  return parts[parts.length - 1].slice(0, -3);
72491
72870
  return null;
72492
72871
  }
72493
- var AGENTS_MD_PATH, CLAUDE_MD_PATH, README_PATH, GITATTRIBUTES_PATH, WORKSPACE_TOML_PATH, AGENTS_DIR, STEERING_DIR, GOVERNANCE_TOML_PATH, SKILLS_DIR, TOOLS_DIR, TOOL_SERVERS_DIR, POLICY_DIR, CEDAR_SCHEMA_PATH, CODEGRAPH_SETTINGS_DIR, SANDBOX_TEMPLATE_DIR, SKILL_FILE_NAME, SERVER_TOML_NAME, TOOLS_TOML_NAME, TOOLS_LOCK_NAME, LEDGER_ROTATIONS, LEDGER_FILE, ROOT_FILES, SERVER_FILES, SANDBOX_SERVICE_NAME, WORKSPACE_LINK_PATH;
72872
+ var AGENTS_MD_PATH, CLAUDE_MD_PATH, README_PATH, GITATTRIBUTES_PATH, WORKSPACE_TOML_PATH, AGENTS_DIR, STEERING_DIR, PEOPLE_DIR, PERSON_FOLDER, GOVERNANCE_TOML_PATH, SKILLS_DIR, TOOLS_DIR, TOOL_SERVERS_DIR, POLICY_DIR, CEDAR_SCHEMA_PATH, CODEGRAPH_SETTINGS_DIR, SANDBOX_TEMPLATE_DIR, SKILL_FILE_NAME, SERVER_TOML_NAME, TOOLS_TOML_NAME, TOOLS_LOCK_NAME, LEDGER_ROTATIONS, LEDGER_FILE, ROOT_FILES, SERVER_FILES, SANDBOX_SERVICE_NAME, WORKSPACE_LINK_PATH;
72494
72873
  var init_paths2 = __esm({
72495
72874
  "../../packages/oxagen/src/steering-repo/paths.ts"() {
72496
72875
  "use strict";
@@ -72501,6 +72880,8 @@ var init_paths2 = __esm({
72501
72880
  WORKSPACE_TOML_PATH = "workspace.toml";
72502
72881
  AGENTS_DIR = "agents";
72503
72882
  STEERING_DIR = "steering";
72883
+ PEOPLE_DIR = "people";
72884
+ PERSON_FOLDER = /^usr_[0-9a-z]+$/i;
72504
72885
  GOVERNANCE_TOML_PATH = "steering/governance.toml";
72505
72886
  SKILLS_DIR = "steering/skills";
72506
72887
  TOOLS_DIR = "tools";
@@ -72546,9 +72927,9 @@ var init_paths2 = __esm({
72546
72927
 
72547
72928
  // src/commands/workspace-link.ts
72548
72929
  import { existsSync as existsSync28, mkdirSync as mkdirSync12, readFileSync as readFileSync28 } from "node:fs";
72549
- import { dirname as dirname34, join as join63 } from "node:path";
72930
+ import { dirname as dirname35, join as join64 } from "node:path";
72550
72931
  function workspaceLinkPath(cwd) {
72551
- return join63(cwd, WORKSPACE_LINK_PATH);
72932
+ return join64(cwd, WORKSPACE_LINK_PATH);
72552
72933
  }
72553
72934
  function isRecord9(value) {
72554
72935
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -72602,7 +72983,7 @@ function readWorkspaceLink(cwd) {
72602
72983
  }
72603
72984
  function writeWorkspaceLink(cwd, link) {
72604
72985
  const filePath = workspaceLinkPath(cwd);
72605
- mkdirSync12(dirname34(filePath), { recursive: true });
72986
+ mkdirSync12(dirname35(filePath), { recursive: true });
72606
72987
  atomicWriteFileSync(filePath, JSON.stringify(link, null, 2));
72607
72988
  }
72608
72989
  var LINK_STRING_FIELDS;
@@ -72637,8 +73018,8 @@ __export(steering_exports, {
72637
73018
  toSignal: () => toSignal
72638
73019
  });
72639
73020
  import { execFileSync } from "node:child_process";
72640
- import { existsSync as existsSync29, realpathSync as realpathSync9 } from "node:fs";
72641
- import { dirname as dirname35, join as join64, normalize as normalize2, parse as parsePath } from "node:path";
73021
+ import { existsSync as existsSync29, realpathSync as realpathSync10 } from "node:fs";
73022
+ import { dirname as dirname36, join as join65, normalize as normalize2, parse as parsePath } from "node:path";
72642
73023
  function findProjectRoot(start) {
72643
73024
  const { root } = parsePath(start);
72644
73025
  const rawGitRoot = gitRootOr(start);
@@ -72647,16 +73028,16 @@ function findProjectRoot(start) {
72647
73028
  if (gitRoot !== null) return gitRoot;
72648
73029
  let dir = from;
72649
73030
  for (; ; ) {
72650
- if (existsSync29(join64(dir, PROJECT_DIR_NAME))) return dir;
73031
+ if (existsSync29(join65(dir, PROJECT_DIR_NAME))) return dir;
72651
73032
  if (dir === root) return from;
72652
- const parent = dirname35(dir);
73033
+ const parent = dirname36(dir);
72653
73034
  if (parent === dir) return from;
72654
73035
  dir = parent;
72655
73036
  }
72656
73037
  }
72657
73038
  function realpathOr(path2) {
72658
73039
  try {
72659
- return realpathSync9(path2);
73040
+ return realpathSync10(path2);
72660
73041
  } catch {
72661
73042
  return normalize2(path2);
72662
73043
  }
@@ -72876,7 +73257,7 @@ async function resolveContext(cwd, {
72876
73257
  if (boundRemote === null) {
72877
73258
  belongsHere = false;
72878
73259
  mismatch.push(
72879
- budget.expired() ? `the check ran out of time before it could tell whether a remote of this checkout points at ${fromPlatform.repository}, so Oxagen's answer was ignored` : scope ? `Oxagen's answer is about ${fromPlatform.repository}, the linked workspace's steering repository. No remote of this checkout points at it, so the workspace's steering gates do not apply here` : `Oxagen's answer is about ${fromPlatform.repository}, which no remote of this checkout points at, so it was ignored \u2014 run \`oxagen init\` in this repository to link it to its workspace`
73260
+ budget.expired() ? `the check ran out of time before it could tell whether a remote of this checkout points at ${fromPlatform.repository}, so Oxagen's answer was ignored` : scope ? `Oxagen's answer is about ${fromPlatform.repository}, the linked workspace's steering repository. No remote of this checkout points at it, so the workspace's steering gates do not apply here` : `Oxagen's answer is about ${fromPlatform.repository}, which no remote of this checkout points at, so it was ignored. Run \`oxagen init\` in this repository to link it to its workspace`
72880
73261
  );
72881
73262
  }
72882
73263
  }
@@ -73462,7 +73843,7 @@ var init_common = __esm({
73462
73843
  init_names();
73463
73844
  lineageSchema = external_exports.string().regex(
73464
73845
  STEERING_RECORD_LINEAGE,
73465
- "a lineage is lowercase letters, digits, dots, and hyphens, and starts and ends with a letter or digit"
73846
+ "a record ID is lowercase letters, digits, dots, and hyphens, and starts and ends with a letter or digit"
73466
73847
  );
73467
73848
  repoRefSchema = external_exports.string().regex(
73468
73849
  REPO_REF_PATTERN,
@@ -73486,7 +73867,7 @@ var init_common = __esm({
73486
73867
  );
73487
73868
  recordIdSchema = external_exports.string().regex(
73488
73869
  /^rec_[a-z0-9_]+_[0-9a-f]{12}$/,
73489
- "an id is rec_<lineage slug>_<12 hex characters>, which Oxagen writes on merge. Remove the line and let Oxagen write it."
73870
+ "an id is rec_<record ID slug>_<12 hex characters>, which Oxagen writes on merge. Remove the line and let Oxagen write it."
73490
73871
  );
73491
73872
  sha256Schema2 = external_exports.string().regex(/^sha256:[0-9a-f]{64}$/);
73492
73873
  gitObjectIdSchema = external_exports.string().regex(/^[0-9a-f]{40}(?:[0-9a-f]{24})?$/);
@@ -74044,15 +74425,15 @@ var init_context_steering_shared = __esm({
74044
74425
  );
74045
74426
  lineageIdSchema = external_exports.string().min(1).max(200).regex(
74046
74427
  RECORD_LINEAGE_ID,
74047
- `a lineage id is lowercase letters, digits, dots and hyphens (e.g. ctx.release.notes-format). The id ${GOVERNANCE_LINEAGE} is reserved for governance changes`
74428
+ `a record ID is lowercase letters, digits, dots and hyphens (e.g. ctx.release.notes-format). The id ${GOVERNANCE_LINEAGE} is reserved for governance changes`
74048
74429
  );
74049
74430
  proposedRecordSchema = external_exports.object({
74050
74431
  lineageId: lineageIdSchema.describe(
74051
- "The lineage this proposal is about; the file stem under .oxagen/rules/"
74432
+ "The record ID this suggestion is about; the file stem under .oxagen/rules/"
74052
74433
  ),
74053
74434
  title: external_exports.string().trim().min(1).max(200).optional(),
74054
74435
  label: external_exports.string().trim().min(1).max(STEERING_RECORD_LABEL_MAX).optional().describe(
74055
- "The record's name, at most 36 characters. Omit it to keep the current label. A rename never creates a version and never changes the lineage."
74436
+ "The record's name, at most 36 characters. Omit it to keep the current label. A rename never creates a version and never changes the record ID."
74056
74437
  ),
74057
74438
  kind: recordKindSchema2,
74058
74439
  force: recordForceSchema2,
@@ -74090,7 +74471,7 @@ var init_context_steering_shared = __esm({
74090
74471
  }).strict();
74091
74472
  proposalIdSchema = external_exports.string().regex(
74092
74473
  /^prp_[0-9A-Za-z]+$/,
74093
- "a proposal id is prp_ followed by letters and digits"
74474
+ "a suggestion id is prp_ followed by letters and digits"
74094
74475
  );
74095
74476
  proposalViewSchema = external_exports.object({
74096
74477
  id: proposalIdSchema,
@@ -74304,7 +74685,7 @@ var init_steering_markdown_import_shared = __esm({
74304
74685
  origin: markdownImportOriginSchema.describe(
74305
74686
  "frontmatter for a file that is one steering record already, split for a statement the model split out"
74306
74687
  ),
74307
- lineage: lineageSchema.max(200).describe("The record's lineage, and its file name in the steering repo"),
74688
+ lineage: lineageSchema.max(200).describe("The record's ID, and its file name in the steering repo"),
74308
74689
  label: external_exports.string().trim().min(1).max(STEERING_RECORD_LABEL_MAX).describe("The record's name, at most 36 characters"),
74309
74690
  statement: external_exports.string().trim().min(1).max(MARKDOWN_IMPORT_FILE_CHARS_MAX).describe("What the record tells an agent: the record's body"),
74310
74691
  kind: recordKindSchema,
@@ -74409,7 +74790,7 @@ var init_steering_markdown_import_shared = __esm({
74409
74790
  memory: external_exports.string().nullable().describe(
74410
74791
  "The waiting memory's id (mem_...), or null for any other reason"
74411
74792
  ),
74412
- lineage: external_exports.string().nullable().describe("The published record's lineage, or null for any other reason"),
74793
+ lineage: external_exports.string().nullable().describe("The published record's ID, or null for any other reason"),
74413
74794
  file: external_exports.string().nullable().describe("The file of the earlier row of this import, or null"),
74414
74795
  line: external_exports.number().int().min(1).nullable().describe("The line of the earlier row of this import, or null")
74415
74796
  }).strict();
@@ -83793,7 +84174,7 @@ var init_columns = __esm({
83793
84174
  import { createHash as createHash18 } from "node:crypto";
83794
84175
  function digestToBytes(digest6) {
83795
84176
  if (!SHA256_DIGEST_PATTERN.test(digest6)) {
83796
- throw new TypeError(`not a sha256 digest: ${digest6}`);
84177
+ throw new TypeError(`not a sha256 hash: ${digest6}`);
83797
84178
  }
83798
84179
  return Buffer.from(digest6.slice("sha256:".length), "hex");
83799
84180
  }
@@ -84122,17 +84503,17 @@ function manifestProblem(manifest) {
84122
84503
  return void 0;
84123
84504
  }
84124
84505
  function attestationFileProblem(file) {
84125
- if (file === null) return "attestation is not a JSON object";
84506
+ if (file === null) return "attestation.json is not a JSON object";
84126
84507
  const attestations = file["attestations"];
84127
84508
  if (attestations === void 0) return void 0;
84128
84509
  if (!Array.isArray(attestations))
84129
- return "attestation attestations is not a list";
84510
+ return "the `attestations` member of attestation.json is not a list";
84130
84511
  const walkable = attestations.every((attestation) => {
84131
84512
  const payload = asRecord2(asRecord2(attestation)?.["payload"]);
84132
84513
  return payload !== null && isCount2(payload["frame_count"]);
84133
84514
  });
84134
84515
  if (!walkable)
84135
- return "an attestation lacks a payload with a whole frame_count";
84516
+ return "a lock in attestation.json lacks a payload with a whole frame_count";
84136
84517
  return void 0;
84137
84518
  }
84138
84519
  function manifestOf(value, checks) {
@@ -84148,7 +84529,11 @@ function attestationFileOf(value, checks) {
84148
84529
  const file = asRecord2(value);
84149
84530
  const problem = attestationFileProblem(file);
84150
84531
  if (problem !== void 0) {
84151
- checks.push({ name: "attestation", status: "broken", detail: problem });
84532
+ checks.push({
84533
+ name: "attestation.json",
84534
+ status: "broken",
84535
+ detail: problem
84536
+ });
84152
84537
  return null;
84153
84538
  }
84154
84539
  return file;
@@ -84166,7 +84551,7 @@ function verifyRunExport(files2) {
84166
84551
  const manifestJson = parseJson2(files2["manifest.json"], "manifest", checks);
84167
84552
  const attestationJson = parseJson2(
84168
84553
  files2["attestation.json"],
84169
- "attestation",
84554
+ "attestation.json",
84170
84555
  checks
84171
84556
  );
84172
84557
  const manifest = manifestOf(manifestJson, checks);
@@ -84276,7 +84661,7 @@ function verifyRunExport(files2) {
84276
84661
  }
84277
84662
  if (digestOf3(frame2) === null) {
84278
84663
  digest6 = "broken";
84279
- reasons.push("frame carries no sha256 digest");
84664
+ reasons.push("frame carries no sha256 hash");
84280
84665
  }
84281
84666
  verdicts.push({
84282
84667
  line,
@@ -84292,8 +84677,8 @@ function verifyRunExport(files2) {
84292
84677
  hold(
84293
84678
  `stream ${attempt.attempt_id}`,
84294
84679
  stream === attempt.event_stream_digest,
84295
- "the frames fold to the sealed event_stream_digest",
84296
- `the frames fold to ${stream}, the seal recorded ${attempt.event_stream_digest}`
84680
+ "the frames fold to the locked event_stream_digest",
84681
+ `the frames fold to ${stream}, the lock recorded ${attempt.event_stream_digest}`
84297
84682
  );
84298
84683
  }
84299
84684
  offset += attempt.frame_count;
@@ -84307,7 +84692,7 @@ function verifyRunExport(files2) {
84307
84692
  status: "broken",
84308
84693
  digest: "broken",
84309
84694
  link: "broken",
84310
- reasons: ["frame lies outside every attested attempt"]
84695
+ reasons: ["frame lies outside every locked attempt"]
84311
84696
  });
84312
84697
  }
84313
84698
  verdicts.sort((a, b3) => a.line - b3.line);
@@ -84334,7 +84719,7 @@ function verifyRunExport(files2) {
84334
84719
  keyId = null;
84335
84720
  }
84336
84721
  hold(
84337
- "attester key",
84722
+ "lock key",
84338
84723
  keyId !== null && keyId === attestationFile.key_id && keyId === manifest.attester_key_id,
84339
84724
  `key ${String(keyId)}`,
84340
84725
  "the bundled public key does not match the recorded key id"
@@ -84344,10 +84729,10 @@ function verifyRunExport(files2) {
84344
84729
  attestations.forEach((a, i2) => {
84345
84730
  const attemptId = a.payload?.attempt_id ?? `#${i2 + 1}`;
84346
84731
  hold(
84347
- `signature ${attemptId}`,
84732
+ `lock ${attemptId}`,
84348
84733
  keyId !== null && verifyAttestation(a, pem),
84349
- "Ed25519 signature verifies",
84350
- "the attestation signature does not verify"
84734
+ "the Ed25519 lock verifies",
84735
+ "the lock does not verify"
84351
84736
  );
84352
84737
  const slice = digests.slice(
84353
84738
  covered,
@@ -84360,30 +84745,30 @@ function verifyRunExport(files2) {
84360
84745
  hold(
84361
84746
  `exported content ${attemptId}`,
84362
84747
  exportedDigest === a.payload?.archive_segment_digest,
84363
- "the exported frame bytes match the signed segment digest",
84364
- "the exported frame bytes do not match the signed segment digest"
84748
+ "the exported frame bytes match the locked segment hash",
84749
+ "the exported frame bytes do not match the locked segment hash"
84365
84750
  );
84366
84751
  }
84367
84752
  hold(
84368
84753
  `run identity ${attemptId}`,
84369
84754
  a.payload?.run_id === manifest.run_id,
84370
- "the attestation names this run",
84371
- "the manifest run differs from the signed run"
84755
+ "the lock names this run",
84756
+ "the manifest run differs from the locked run"
84372
84757
  );
84373
84758
  covered += a.payload?.frame_count ?? 0;
84374
84759
  const attemptRoot = slice.every((d) => d !== null) ? merkleRoot(slice) : null;
84375
84760
  hold(
84376
- `attested root ${attemptId}`,
84761
+ `locked root ${attemptId}`,
84377
84762
  attemptRoot === a.payload?.merkle_root,
84378
- "the attempt's frames hash to the signed root",
84379
- `the attempt's frames hash to ${attemptRoot ?? "nothing"}, the attestation signed ${String(a.payload?.merkle_root)}`
84763
+ "the attempt's frames hash to the locked root",
84764
+ `the attempt's frames hash to ${attemptRoot ?? "nothing"}, the lock holds ${String(a.payload?.merkle_root)}`
84380
84765
  );
84381
84766
  });
84382
84767
  hold(
84383
84768
  "coverage",
84384
84769
  covered === frames.length && attestations.length > 0,
84385
- "the attestations cover every frame",
84386
- `the attestations cover ${covered} of ${frames.length} frames`
84770
+ "the locks cover every frame",
84771
+ `the locks cover ${covered} of ${frames.length} frames`
84387
84772
  );
84388
84773
  let redactions = null;
84389
84774
  const redactionsText = files2["redactions.json"];
@@ -84977,7 +85362,7 @@ var init_record = __esm({
84977
85362
  "Tool names, or <server>__* prefixes. The record reaches a request only when the run's toolbelt holds a match."
84978
85363
  ),
84979
85364
  skills: uniqueArray(lineageSchema, "skills", 1).optional().describe(
84980
- "Skill lineages. The record reaches a request only when the request's context.skill is on the list. A record cannot target a named agent."
85365
+ "Skill record IDs. The record reaches a request only when the request's context.skill is on the list. A record cannot target a named agent."
84981
85366
  ),
84982
85367
  toolbelt: external_exports.string().min(1).optional().describe(
84983
85368
  "A named toolbelt in tools/toolbelts/. The steering repo spec defers what it does to a later version."
@@ -85345,7 +85730,7 @@ var init_codegraph_settings = __esm({
85345
85730
  ),
85346
85731
  key_hint: external_exports.string().regex(/^.{4}$/u, "a key hint is the key's last 4 characters").optional().describe("The last 4 characters of the organization's key."),
85347
85732
  linker_model: modelId().optional().describe(
85348
- "The model that judges candidate links. Unset: GLM 5.3 Flash, or GLM 5.2 where 5.3 Flash has no batch option."
85733
+ "The model that judges suggested links. Unset: GLM 5.3 Flash, or GLM 5.2 where 5.3 Flash has no batch option."
85349
85734
  ),
85350
85735
  stronger_model: modelId().optional().describe(
85351
85736
  "The model for cross-repo pairs the linker model could not settle. Unset: GLM 5.3."
@@ -85645,7 +86030,7 @@ var init_codegraph_settings = __esm({
85645
86030
  7
85646
86031
  ),
85647
86032
  stale_proposal_days: setting(
85648
- external_exports.number().int().min(1).describe("A proposal untouched this many days is stale."),
86033
+ external_exports.number().int().min(1).describe("A suggestion untouched this many days is stale."),
85649
86034
  30
85650
86035
  ),
85651
86036
  package_categories: uniqueArray(
@@ -85834,7 +86219,7 @@ var init_codegraph_settings = __esm({
85834
86219
  group: "decisions",
85835
86220
  id: "codegraph-decisions/v1",
85836
86221
  title: "Code graph decision records",
85837
- description: "codegraph/decisions.toml: the importance threshold, grouping window, stale-proposal age, and package categories.",
86222
+ description: "codegraph/decisions.toml: the importance threshold, grouping window, stale-suggestion age, and package categories.",
85838
86223
  schema: codegraphDecisionsSchema,
85839
86224
  defaults: CODEGRAPH_DECISIONS_DEFAULTS,
85840
86225
  timing: "next_build"
@@ -86002,7 +86387,7 @@ var init_promotion = __esm({
86002
86387
  "The hash of the line before, or null on the first line of the chain."
86003
86388
  ),
86004
86389
  hash: sha256Schema2.describe(
86005
- "sha256 over the RFC 8785 canonical JSON of this line without hash."
86390
+ "sha256 of this line without hash, as JSON in one standard form (RFC 8785)."
86006
86391
  )
86007
86392
  }).strict();
86008
86393
  }
@@ -86083,7 +86468,7 @@ var init_digest_shared = __esm({
86083
86468
  "../../packages/oxagen/src/contracts/digest.shared.ts"() {
86084
86469
  "use strict";
86085
86470
  init_zod();
86086
- sha256DigestSchema = external_exports.string().regex(/^sha256:[0-9a-f]{64}$/, "a sha256 digest (sha256:<64 hex>)");
86471
+ sha256DigestSchema = external_exports.string().regex(/^sha256:[0-9a-f]{64}$/, "a sha256 hash (sha256:<64 hex>)");
86087
86472
  }
86088
86473
  });
86089
86474
 
@@ -86978,7 +87363,7 @@ var init_workspace2 = __esm({
86978
87363
  "Identical calls in a row that stop a run counting as progress. 2 or more."
86979
87364
  ),
86980
87365
  mode: noProgressModeSchema.describe(
86981
- "observe records each run that reaches the limit, and runs keep going. enforced also pauses the run at its next checkpoint."
87366
+ "observe records each run that reaches the limit, and runs keep going. enforced also pauses the run before its next step."
86982
87367
  )
86983
87368
  }).strict();
86984
87369
  workspaceSchema = external_exports.object({
@@ -87079,7 +87464,7 @@ var init_steering_tools = __esm({
87079
87464
  STEERING_SEARCH_SNIPPET_MAX = 160;
87080
87465
  steeringSearchInputSchema = external_exports.object({
87081
87466
  query: external_exports.string().max(500).optional().describe(
87082
- "Words to look for in each record's label, description, lineage, and body. A label match ranks above a description match, and a description match above a body match."
87467
+ "Words to look for in each record's label, description, record ID, and body. A label match ranks above a description match, and a description match above a body match."
87083
87468
  ),
87084
87469
  kind: recordKindSchema.optional().describe("Only records of this kind, such as skill."),
87085
87470
  kinds: external_exports.array(recordKindSchema).min(1).max(20).optional().describe(
@@ -87261,9 +87646,12 @@ function isRecordKind(kind) {
87261
87646
  function isRecordPath(path2) {
87262
87647
  return isRecordKind(classifySteeringRepoPath(path2));
87263
87648
  }
87649
+ function isReadRecordKind(kind) {
87650
+ return isRecordKind(kind) || kind === "person-record";
87651
+ }
87264
87652
  function readRecordFile(path2, text5) {
87265
87653
  const kind = classifySteeringRepoPath(path2);
87266
- if (!isRecordKind(kind)) return null;
87654
+ if (!isReadRecordKind(kind)) return null;
87267
87655
  const split = splitRecordFile(text5);
87268
87656
  if (!split.ok) return null;
87269
87657
  const parsed2 = parseFrontmatter(split.parts.frontmatter);
@@ -87650,6 +88038,9 @@ function sameBudget(a, b3) {
87650
88038
  function entryText(entry2) {
87651
88039
  return `${entry2.lineage} (${formatCount(entry2.tokens)} tokens)`;
87652
88040
  }
88041
+ function workspaceRecords(env) {
88042
+ return env.records.filter((file) => file.kind !== "person-record");
88043
+ }
87653
88044
  function changedRecordTokens(env) {
87654
88045
  const lines = [];
87655
88046
  for (const file of env.records) {
@@ -87685,7 +88076,10 @@ function alwaysOnPart(env) {
87685
88076
  const budgetMoved = env.base !== null && !sameBudget(budget, alwaysOnBudget(env.base));
87686
88077
  const before = /* @__PURE__ */ new Map();
87687
88078
  if (env.base !== null && env.baseRecords !== null)
87688
- for (const block of alwaysOnBlocks(env.base, env.baseRecords))
88079
+ for (const block of alwaysOnBlocks(
88080
+ env.base,
88081
+ env.baseRecords.filter((file) => file.kind !== "person-record")
88082
+ ))
87689
88083
  before.set(block.repository, block);
87690
88084
  const governance = env.head.get(GOVERNANCE_TOML_PATH);
87691
88085
  const line = governance === void 0 ? null : tomlLine(governance, "steering.always_on_tokens");
@@ -87693,7 +88087,7 @@ function alwaysOnPart(env) {
87693
88087
  const notes = [];
87694
88088
  const ceiling = budgetCeiling(budget, line);
87695
88089
  if (ceiling !== null) findings.push(ceiling);
87696
- for (const block of alwaysOnBlocks(env.head, env.records)) {
88090
+ for (const block of alwaysOnBlocks(env.head, workspaceRecords(env))) {
87697
88091
  const prior = before.get(block.repository);
87698
88092
  if (!budgetMoved && prior?.text === block.text) continue;
87699
88093
  const priorTokens = prior?.tokens ?? 0;
@@ -88085,7 +88479,7 @@ function flips(env) {
88085
88479
  ...place(file, "effect"),
88086
88480
  message: `The published constraint ${record.lineage} is a ${before}, and this change makes it a ${record.effect}.`,
88087
88481
  expected: `effect: ${before}, as published.`,
88088
- fix: "Archive this record, and open a new record with its own lineage for the opposite effect."
88482
+ fix: "Archive this record, and open a new record with its own record ID for the opposite effect."
88089
88483
  })
88090
88484
  );
88091
88485
  }
@@ -88179,9 +88573,9 @@ var init_lineage = __esm({
88179
88573
  path: file.path,
88180
88574
  line: recordFieldLine(file, "lineage"),
88181
88575
  field: "lineage",
88182
- message: `The lineage ${lineage} is also declared in ${others.join(", ")}.`,
88183
- expected: "One file for each lineage.",
88184
- fix: "Give each record its own lineage, or delete the copy."
88576
+ message: `The record ID ${lineage} is also declared in ${others.join(", ")}.`,
88577
+ expected: "One file for each record ID.",
88578
+ fix: "Give each record its own record ID, or delete the copy."
88185
88579
  })
88186
88580
  );
88187
88581
  }
@@ -88440,12 +88834,12 @@ function recordFieldFindings(file, known) {
88440
88834
  line: at2(`skills.${n2}`),
88441
88835
  field: `skills.${n2}`,
88442
88836
  ...withHint(
88443
- `The record names the skill ${skill}, and no active skill has that lineage.`,
88837
+ `The record names the skill ${skill}, and no active skill has that record ID.`,
88444
88838
  skill,
88445
88839
  skillList
88446
88840
  ),
88447
- expected: "The lineage of an active skill under steering/skills/.",
88448
- fix: `Correct the lineage, or add the skill at steering/skills/${skill}/SKILL.md.`
88841
+ expected: "The record ID of an active skill under steering/skills/.",
88842
+ fix: `Correct the record ID, or add the skill at steering/skills/${skill}/SKILL.md.`
88449
88843
  })
88450
88844
  );
88451
88845
  });
@@ -88681,13 +89075,13 @@ var init_references = __esm({
88681
89075
  init_repo2();
88682
89076
  find8 = finder("references");
88683
89077
  MENTION_TEXT = {
88684
- record: "the lineage of an active record",
88685
- skill: "the lineage of an active skill",
89078
+ record: "the record ID of an active record",
89079
+ skill: "the record ID of an active skill",
88686
89080
  tool: "a tool the workspace imports"
88687
89081
  };
88688
89082
  MENTION_MISS = {
88689
- record: "no active record has that lineage",
88690
- skill: "no active skill has that lineage",
89083
+ record: "no active record has that record ID",
89084
+ skill: "no active skill has that record ID",
88691
89085
  tool: "no server in the workspace imports that tool"
88692
89086
  };
88693
89087
  FILE_MENTION = /(^|[\s(`'"])@([A-Za-z0-9_][A-Za-z0-9_./-]*\.[A-Za-z0-9]+)/g;
@@ -88909,16 +89303,16 @@ function recordShape2(file) {
88909
89303
  const lineage = file.raw.lineage;
88910
89304
  if (!isString(lineage)) return findings;
88911
89305
  const parts = file.path.split("/");
88912
- if (file.kind === "record" && fileStem(file.path) !== lineage) {
89306
+ if (file.kind !== "skill-record" && fileStem(file.path) !== lineage) {
88913
89307
  findings.push(
88914
89308
  find9({
88915
89309
  rule: "file-named-for-lineage",
88916
89310
  path: file.path,
88917
89311
  line: recordFieldLine(file, "lineage"),
88918
89312
  field: "lineage",
88919
- message: `The file is named ${fileStem(file.path)}.md, but its lineage is ${lineage}.`,
88920
- expected: "A record file named <lineage>.md.",
88921
- fix: `Rename the file to ${lineage}.md, or correct the lineage.`
89313
+ message: `The file is named ${fileStem(file.path)}.md, but its record ID is ${lineage}.`,
89314
+ expected: "A record file named <record ID>.md.",
89315
+ fix: `Rename the file to ${lineage}.md, or correct the record ID.`
88922
89316
  })
88923
89317
  );
88924
89318
  }
@@ -88929,9 +89323,9 @@ function recordShape2(file) {
88929
89323
  path: file.path,
88930
89324
  line: recordFieldLine(file, "lineage"),
88931
89325
  field: "lineage",
88932
- message: `The skill's folder is named ${parts[2]}, but its lineage is ${lineage}.`,
88933
- expected: `A skill at ${SKILLS_DIR}/<lineage>/${SKILL_FILE_NAME}.`,
88934
- fix: `Rename the folder to ${lineage}, or correct the lineage.`
89326
+ message: `The skill's folder is named ${parts[2]}, but its record ID is ${lineage}.`,
89327
+ expected: `A skill at ${SKILLS_DIR}/<record ID>/${SKILL_FILE_NAME}.`,
89328
+ fix: `Rename the folder to ${lineage}, or correct the record ID.`
88935
89329
  })
88936
89330
  );
88937
89331
  }
@@ -88944,7 +89338,7 @@ function recordShape2(file) {
88944
89338
  line: recordFieldLine(file, "kind"),
88945
89339
  field: "kind",
88946
89340
  message: `A skill must live in its own folder under ${SKILLS_DIR}.`,
88947
- expected: `A skill at ${SKILLS_DIR}/<lineage>/${SKILL_FILE_NAME}.`,
89341
+ expected: `A skill at ${SKILLS_DIR}/<record ID>/${SKILL_FILE_NAME}.`,
88948
89342
  fix: `Move the file to ${SKILLS_DIR}/${lineage}/${SKILL_FILE_NAME}, or change the kind.`
88949
89343
  })
88950
89344
  );
@@ -89168,6 +89562,7 @@ var init_schema2 = __esm({
89168
89562
  const kind = classifySteeringRepoPath(path2);
89169
89563
  switch (kind) {
89170
89564
  case "record":
89565
+ case "person-record":
89171
89566
  case "skill-record":
89172
89567
  findings.push(...readRecord(path2, text5, records.get(path2) ?? null));
89173
89568
  findings.push(...scopeFitsRepo(records.get(path2) ?? null, env.repo));
@@ -89961,7 +90356,7 @@ var init_memory_client = __esm({
89961
90356
  import { readFile as readFile9 } from "node:fs/promises";
89962
90357
  import {
89963
90358
  basename as basename7,
89964
- dirname as dirname36,
90359
+ dirname as dirname37,
89965
90360
  isAbsolute as isAbsolute17,
89966
90361
  relative as relative7,
89967
90362
  resolve as resolve23,
@@ -89973,7 +90368,7 @@ function inside(rel) {
89973
90368
  function importFilename(path2, folder) {
89974
90369
  let rel = relative7(process.cwd(), path2);
89975
90370
  if (!inside(rel) && folder !== void 0) {
89976
- rel = relative7(dirname36(resolve23(folder)), resolve23(path2));
90371
+ rel = relative7(dirname37(resolve23(folder)), resolve23(path2));
89977
90372
  }
89978
90373
  const name = inside(rel) ? rel.split(sep9).join("/") : basename7(path2);
89979
90374
  return name.length > 256 ? basename7(path2).slice(-256) : name;
@@ -90268,7 +90663,7 @@ __export(steering_import_exports, {
90268
90663
  });
90269
90664
  import { readdir as readdir4, realpath as realpath2, stat as stat4 } from "node:fs/promises";
90270
90665
  import { homedir as homedir13 } from "node:os";
90271
- import { basename as basename8, extname, join as join65, relative as relative8, sep as sep10 } from "node:path";
90666
+ import { basename as basename8, extname, join as join66, relative as relative8, sep as sep10 } from "node:path";
90272
90667
  function envDir2(env, key) {
90273
90668
  const value = env[key];
90274
90669
  return value === void 0 || value.trim() === "" ? null : value;
@@ -90276,34 +90671,34 @@ function envDir2(env, key) {
90276
90671
  function harnessHome(harness, env = process.env, home = homedir13()) {
90277
90672
  switch (harness) {
90278
90673
  case "claude-code": {
90279
- const config = envDir2(env, "CLAUDE_CONFIG_DIR") ?? join65(home, ".claude");
90674
+ const config = envDir2(env, "CLAUDE_CONFIG_DIR") ?? join66(home, ".claude");
90280
90675
  return {
90281
90676
  harness,
90282
90677
  folders: [
90283
90678
  {
90284
- dir: skillsRoot("claude-code", env, home) ?? join65(config, "skills"),
90679
+ dir: skillsRoot("claude-code", env, home) ?? join66(config, "skills"),
90285
90680
  mount: ".claude/skills"
90286
90681
  },
90287
- { dir: join65(config, "commands"), mount: ".claude/commands" },
90288
- { dir: join65(config, "agents"), mount: ".claude/agents" }
90682
+ { dir: join66(config, "commands"), mount: ".claude/commands" },
90683
+ { dir: join66(config, "agents"), mount: ".claude/agents" }
90289
90684
  ],
90290
90685
  instructions: [
90291
- { file: join65(config, "CLAUDE.md"), filename: ".claude/CLAUDE.md" }
90686
+ { file: join66(config, "CLAUDE.md"), filename: ".claude/CLAUDE.md" }
90292
90687
  ]
90293
90688
  };
90294
90689
  }
90295
90690
  case "codex": {
90296
- const codexHome = envDir2(env, "CODEX_HOME") ?? join65(home, ".codex");
90691
+ const codexHome = envDir2(env, "CODEX_HOME") ?? join66(home, ".codex");
90297
90692
  return {
90298
90693
  harness,
90299
90694
  folders: [
90300
90695
  {
90301
- dir: skillsRoot("codex", env, home) ?? join65(home, ".agents", "skills"),
90696
+ dir: skillsRoot("codex", env, home) ?? join66(home, ".agents", "skills"),
90302
90697
  mount: ".agents/skills"
90303
90698
  }
90304
90699
  ],
90305
90700
  instructions: ["AGENTS.override.md", "AGENTS.md"].map((name) => ({
90306
- file: join65(codexHome, name),
90701
+ file: join66(codexHome, name),
90307
90702
  filename: `.codex/${name}`
90308
90703
  }))
90309
90704
  };
@@ -90312,8 +90707,8 @@ function harnessHome(harness, env = process.env, home = homedir13()) {
90312
90707
  return {
90313
90708
  harness,
90314
90709
  folders: [
90315
- { dir: join65(home, ".cursor", "skills"), mount: ".cursor/skills" },
90316
- { dir: join65(home, ".cursor", "commands"), mount: ".cursor/commands" }
90710
+ { dir: join66(home, ".cursor", "skills"), mount: ".cursor/skills" },
90711
+ { dir: join66(home, ".cursor", "commands"), mount: ".cursor/commands" }
90317
90712
  ],
90318
90713
  instructions: []
90319
90714
  };
@@ -90359,7 +90754,7 @@ async function findMarkdownFiles(paths, harness) {
90359
90754
  }
90360
90755
  const found = [];
90361
90756
  for (const entry2 of entries2.sort(byName)) {
90362
- const path2 = join65(dir, entry2.name);
90757
+ const path2 = join66(dir, entry2.name);
90363
90758
  if (entry2.isDirectory()) {
90364
90759
  if (!entry2.name.startsWith(".") && entry2.name !== "node_modules")
90365
90760
  found.push(...await filesUnder(path2, from));
@@ -90381,7 +90776,7 @@ async function findMarkdownFiles(paths, harness) {
90381
90776
  const { folder } = frame2;
90382
90777
  const named = (rel) => frame2.fixedNames ? { filename: rel } : {};
90383
90778
  for (const entry2 of entries2) {
90384
- const path2 = join65(dir, entry2.name);
90779
+ const path2 = join66(dir, entry2.name);
90385
90780
  const rel = frame2.relOf(path2);
90386
90781
  if (entry2.isDirectory()) {
90387
90782
  if (entry2.name === "node_modules") continue;
@@ -90440,7 +90835,7 @@ async function findMarkdownFiles(paths, harness) {
90440
90835
  }
90441
90836
  if (folderGiven) {
90442
90837
  const catalogue = CATALOGUE_FOLDERS.has(basename8(path2));
90443
- const root = catalogue ? join65(path2, "..") : path2;
90838
+ const root = catalogue ? join66(path2, "..") : path2;
90444
90839
  await walk2(path2, {
90445
90840
  relOf: (p) => under(root, p),
90446
90841
  folder: path2,
@@ -90604,7 +90999,7 @@ async function steeringPromote(findingId, opts = {}, writer = stdoutWriter) {
90604
90999
  return;
90605
91000
  }
90606
91001
  writer.write(
90607
- `Opened proposal ${result2.proposal_id} for record ${result2.lineage}.`
91002
+ `Opened suggestion ${result2.proposal_id} for record ${result2.lineage}.`
90608
91003
  );
90609
91004
  const pr = result2.pull_request;
90610
91005
  writer.write(
@@ -90627,7 +91022,7 @@ var init_steering_promote = __esm({
90627
91022
  USAGE2 = "oxagen steering promote <finding-id> [--json]";
90628
91023
  NEXT_STEPS2 = {
90629
91024
  finding_resolved: "Run `oxagen steering findings` to see the statements that still match a record.",
90630
- already_proposed: "Run `oxagen steering findings` to see the open proposal and its steering PR.",
91025
+ already_proposed: "Run `oxagen steering findings` to see the open suggestion and its steering PR.",
90631
91026
  lineage_pr_open: "Merge or close the PR that is open on the record, then promote the finding again."
90632
91027
  };
90633
91028
  }
@@ -90650,7 +91045,7 @@ async function steeringRestoreBlock(proposalId, path2, opts = {}, writer = stdou
90650
91045
  if (!PROPOSAL_ID2.test(id2)) {
90651
91046
  usageError(
90652
91047
  writer,
90653
- `expected a proposal id that starts with prp_, got ${JSON.stringify(proposalId)}`,
91048
+ `expected a suggestion id that starts with prp_, got ${JSON.stringify(proposalId)}`,
90654
91049
  USAGE3
90655
91050
  );
90656
91051
  return;
@@ -90704,9 +91099,9 @@ var init_steering_restore_block = __esm({
90704
91099
  NEXT_STEPS3 = {
90705
91100
  no_managed_block: "Remove the marker lines and the text between them from the file on the PR's branch by hand.",
90706
91101
  no_managed_blocks: "The repository keeps its steering under .oxagen/. Edit the file on the PR's branch directly.",
90707
- pr_not_open: "Run `oxagen steering findings` to see the proposal's current steering PR."
91102
+ pr_not_open: "Run `oxagen steering findings` to see the suggestion's current steering PR."
90708
91103
  };
90709
- USAGE3 = "oxagen steering restore-block <proposal-id> <AGENTS.md|CLAUDE.md|README.md> [--json]";
91104
+ USAGE3 = "oxagen steering restore-block <suggestion-id> <AGENTS.md|CLAUDE.md|README.md> [--json]";
90710
91105
  }
90711
91106
  });
90712
91107
 
@@ -90934,7 +91329,7 @@ async function terminalSession(relay, mode, runName, io, writer) {
90934
91329
  if (detaching) {
90935
91330
  writer.writeErr(
90936
91331
  `
90937
- Detached. The run keeps going. Open its terminal again with \`oxagen sandbox attach ${runName}\`.`
91332
+ You left the terminal. The run keeps going. Open its terminal again with \`oxagen sandbox attach ${runName}\`.`
90938
91333
  );
90939
91334
  } else if (result2?.message) {
90940
91335
  writer.writeErr(`
@@ -91269,7 +91664,7 @@ async function runExport(runId, opts = {}, writer = stdoutWriter) {
91269
91664
  }
91270
91665
  writer.write(`Export ${result2.exportId} queued for ${runId}.`);
91271
91666
  writer.write(
91272
- `The bundle holds the frames as NDJSON, the Merkle root, the attestation, the verifying key, and a verifier script. Check on it with \`oxagen run export-status ${result2.exportId}\`.`
91667
+ `The bundle holds the frames as NDJSON, the Merkle root, Oxagen's lock, the key that checks the lock, and a verifier script. Check on it with \`oxagen run export-status ${result2.exportId}\`.`
91273
91668
  );
91274
91669
  }
91275
91670
  function resolveDownloadUrl(url, apiUrl) {
@@ -91312,7 +91707,7 @@ async function runExportStatus(exportId, opts = {}, writer = stdoutWriter) {
91312
91707
  return;
91313
91708
  }
91314
91709
  writer.write(`Size: ${formatBytes2(result2.bundleBytes)}`);
91315
- writer.write(`Digest: ${result2.bundleDigest ?? "not recorded"}`);
91710
+ writer.write(`Hash: ${result2.bundleDigest ?? "not recorded"}`);
91316
91711
  writer.write(`Frames: ${result2.frameCount ?? "not recorded"}`);
91317
91712
  writer.write(`Merkle root: ${result2.merkleRoot ?? "not recorded"}`);
91318
91713
  if (result2.download) {
@@ -91343,7 +91738,7 @@ async function runDownload(exportId, opts = {}, writer = stdoutWriter) {
91343
91738
  }
91344
91739
  if (!status2.download || !status2.bundleDigest) {
91345
91740
  out.error(
91346
- `Export ${exportId} is ready but the platform sent no download link or digest.`,
91741
+ `Export ${exportId} is ready but the platform sent no download link or hash.`,
91347
91742
  "not_ready"
91348
91743
  );
91349
91744
  return;
@@ -91426,7 +91821,7 @@ async function runDownload(exportId, opts = {}, writer = stdoutWriter) {
91426
91821
  return;
91427
91822
  }
91428
91823
  writer.write(`Wrote ${path2} (${formatBytes2(size)}).`);
91429
- writer.write(`Digest ${actual} matches the recorded bundle digest.`);
91824
+ writer.write(`Hash ${actual} matches the recorded bundle hash.`);
91430
91825
  writer.write(`Check every frame offline with \`oxagen verify ${path2}\`.`);
91431
91826
  }
91432
91827
  function attestationLine(attestation) {
@@ -91453,7 +91848,7 @@ async function runChain(runId, opts = {}, writer = stdoutWriter) {
91453
91848
  const many = result2.seals.length > 1;
91454
91849
  result2.seals.forEach((seal2, i2) => {
91455
91850
  writer.write(
91456
- `${many ? `Attempt ${i2 + 1} attestation` : "Attestation"}: ${attestationLine(seal2.attestation)}`
91851
+ `${many ? `Attempt ${i2 + 1} lock` : "Lock"}: ${attestationLine(seal2.attestation)}`
91457
91852
  );
91458
91853
  });
91459
91854
  writer.write(
@@ -91477,7 +91872,9 @@ async function runChain(runId, opts = {}, writer = stdoutWriter) {
91477
91872
  }
91478
91873
  }
91479
91874
  if (result2.checkpoints.length > 0) {
91480
- writer.write(`${result2.checkpoints.length} signed checkpoint(s).`);
91875
+ writer.write(
91876
+ `The agent's computer locked the record at ${result2.checkpoints.length} point(s) along the way.`
91877
+ );
91481
91878
  }
91482
91879
  const chains = result2.chains ?? [];
91483
91880
  if (chains.length > 0) {
@@ -91486,7 +91883,7 @@ async function runChain(runId, opts = {}, writer = stdoutWriter) {
91486
91883
  for (const chain of chains) {
91487
91884
  const name = chain.subagentType ?? chain.subagentId ?? chain.sessionUuid;
91488
91885
  writer.write(
91489
- ` ${name} (${chain.sessionUuid}): ${chain.frameCount} frames, ${chain.gaps.missingFrameCount} missing frames, ${chain.gaps.missingBodies} missing bodies${chain.sealedAt === null ? ", unsealed" : ""}${chain.complete ? "" : ", cut short"}`
91886
+ ` ${name} (${chain.sessionUuid}): ${chain.frameCount} frames, ${chain.gaps.missingFrameCount} missing frames, ${chain.gaps.missingBodies} missing bodies${chain.sealedAt === null ? ", not locked" : ""}${chain.complete ? "" : ", cut short"}`
91490
91887
  );
91491
91888
  }
91492
91889
  }
@@ -91774,7 +92171,7 @@ async function runShow(runId, opts = {}, writer = stdoutWriter) {
91774
92171
  writer.write(`Steering: ${steeringOf(run3)}`);
91775
92172
  writer.write(`Replay grade: ${run3.replayGrade ?? NOT_RECORDED}`);
91776
92173
  writer.write(`Started: ${run3.startedAt}`);
91777
- writer.write(`Sealed: ${run3.sealedAt ?? "not sealed"}`);
92174
+ writer.write(`Locked: ${run3.sealedAt ?? "not locked"}`);
91778
92175
  writer.write(`Turns: ${run3.turns ?? NOT_RECORDED}`);
91779
92176
  writer.write(`Steps: ${run3.steps}`);
91780
92177
  writer.write(`Frames: ${run3.frames}`);
@@ -92765,7 +93162,7 @@ function unzipSync(data, opts) {
92765
93162
  }
92766
93163
  return files2;
92767
93164
  }
92768
- var require2, _a, Worker, isMarkedAsUntransferable, u82, u162, i32, fleb, fdeb, clim, freb, _a, fl, revfl, _b, fd, revfd, rev, x, i, hMap, flt, i, i, i, i, fdt, i, flrm, fdrm, max, bits, bits16, shft, slc, ec, err, inflt, et, b2, b4, b8, td, tds, dutf8, slzh, zh, z64hs;
93165
+ var require2, _a, Worker, isMarkedAsUntransferable, u82, u162, i322, fleb, fdeb, clim, freb, _a, fl, revfl, _b, fd, revfd, rev, x, i, hMap, flt, i, i, i, i, fdt, i, flrm, fdrm, max, bits, bits16, shft, slc, ec, err, inflt, et, b2, b4, b8, td, tds, dutf8, slzh, zh, z64hs;
92769
93166
  var init_esm2 = __esm({
92770
93167
  "../../node_modules/.pnpm/fflate@0.8.3/node_modules/fflate/esm/index.mjs"() {
92771
93168
  require2 = createRequire3("/");
@@ -92775,7 +93172,7 @@ var init_esm2 = __esm({
92775
93172
  }
92776
93173
  u82 = Uint8Array;
92777
93174
  u162 = Uint16Array;
92778
- i32 = Int32Array;
93175
+ i322 = Int32Array;
92779
93176
  fleb = new u82([
92780
93177
  0,
92781
93178
  0,
@@ -92853,7 +93250,7 @@ var init_esm2 = __esm({
92853
93250
  for (var i2 = 0; i2 < 31; ++i2) {
92854
93251
  b3[i2] = start += 1 << eb[i2 - 1];
92855
93252
  }
92856
- var r = new i32(b3[30]);
93253
+ var r = new i322(b3[30]);
92857
93254
  for (var i2 = 1; i2 < 30; ++i2) {
92858
93255
  for (var j = b3[i2]; j < b3[i2 + 1]; ++j) {
92859
93256
  r[j] = j - b3[i2] << 5 | i2;
@@ -93190,11 +93587,11 @@ __export(verify_exports, {
93190
93587
  readBundle: () => readBundle,
93191
93588
  verifyBundle: () => verifyBundle3
93192
93589
  });
93193
- import { existsSync as existsSync30, readFileSync as readFileSync30, statSync as statSync18 } from "node:fs";
93194
- import { join as join66 } from "node:path";
93590
+ import { existsSync as existsSync30, readFileSync as readFileSync30, statSync as statSync19 } from "node:fs";
93591
+ import { join as join67 } from "node:path";
93195
93592
  function readDirectory(dir) {
93196
93593
  const read2 = (name) => {
93197
- const path2 = join66(dir, name);
93594
+ const path2 = join67(dir, name);
93198
93595
  return existsSync30(path2) ? readFileSync30(path2, "utf8") : void 0;
93199
93596
  };
93200
93597
  return assemble(read2, dir);
@@ -93241,7 +93638,7 @@ function readBundle(path2) {
93241
93638
  if (!existsSync30(path2)) {
93242
93639
  throw new BundleReadError(`${path2} does not exist.`);
93243
93640
  }
93244
- return statSync18(path2).isDirectory() ? readDirectory(path2) : readZip(path2);
93641
+ return statSync19(path2).isDirectory() ? readDirectory(path2) : readZip(path2);
93245
93642
  }
93246
93643
  function plural3(count12, one, many) {
93247
93644
  return `${count12} ${count12 === 1 ? one : many}`;
@@ -93255,7 +93652,7 @@ function formatFrame(frame2) {
93255
93652
  `frame ${frame2.line}`,
93256
93653
  where,
93257
93654
  frame2.status,
93258
- `digest ${digestLabel(frame2.digest)}`,
93655
+ `hash ${digestLabel(frame2.digest)}`,
93259
93656
  `link ${frame2.link}`
93260
93657
  ];
93261
93658
  if (frame2.reasons.length > 0) parts.push(frame2.reasons.join("; "));
@@ -93277,7 +93674,7 @@ function formatVerification(result2) {
93277
93674
  ).length;
93278
93675
  if (notCarried > 0) {
93279
93676
  lines.push(
93280
- ` Digest not carried on ${plural3(notCarried, "wrapped (tse_) frame", "wrapped (tse_) frames")}. A wrapped frame is hashed over its full event, and the bundle does not hold that event for these frames: an export before format 3 never did, and a format-3 export leaves it out when the stored row cannot be proven to rebuild it. For these frames, only the links and the Merkle root can be checked.`
93677
+ ` Hash not carried on ${plural3(notCarried, "wrapped (tse_) frame", "wrapped (tse_) frames")}. A wrapped frame is hashed over its full event, and the bundle does not hold that event for these frames: an export before format 3 never did, and a format-3 export leaves it out when the stored row cannot be proven to rebuild it. For these frames, only the links and the Merkle root can be checked.`
93281
93678
  );
93282
93679
  }
93283
93680
  lines.push("");
@@ -94439,7 +94836,7 @@ async function resolveOrg(opts) {
94439
94836
  return promptChoice(
94440
94837
  "Select an organization:",
94441
94838
  organizations,
94442
- (o) => `${o.name} (${o.slug}) \u2014 ${o.role}`,
94839
+ (o) => `${o.name} (${o.slug}), ${o.role}`,
94443
94840
  opts.isTTY
94444
94841
  );
94445
94842
  }
@@ -94472,7 +94869,7 @@ async function resolveWorkspace(opts) {
94472
94869
  const ws = await promptChoice(
94473
94870
  `Select a workspace in ${opts.orgSlug}:`,
94474
94871
  workspaces,
94475
- (w) => `${w.name} (${w.slug})${w.role ? ` \u2014 ${w.role}` : ""}`,
94872
+ (w) => `${w.name} (${w.slug})${w.role ? `, ${w.role}` : ""}`,
94476
94873
  opts.isTTY
94477
94874
  );
94478
94875
  return { org: organization, workspace: ws };
@@ -94510,11 +94907,11 @@ import {
94510
94907
  mkdirSync as mkdirSync13,
94511
94908
  readFileSync as readFileSync31,
94512
94909
  readdirSync as readdirSync15,
94513
- realpathSync as realpathSync10,
94910
+ realpathSync as realpathSync11,
94514
94911
  writeFileSync as writeFileSync9
94515
94912
  } from "node:fs";
94516
94913
  import { homedir as homedir14, hostname as osHostname3 } from "node:os";
94517
- import { join as join67, relative as relative9, resolve as resolve25, sep as sep11 } from "node:path";
94914
+ import { join as join68, relative as relative9, resolve as resolve25, sep as sep11 } from "node:path";
94518
94915
  function git4(cwd, args) {
94519
94916
  return new Promise((done) => {
94520
94917
  try {
@@ -94561,7 +94958,7 @@ function parseRemoteRepository(url) {
94561
94958
  }
94562
94959
  function oxagenPresent(root) {
94563
94960
  try {
94564
- return readdirSync15(join67(root, ".oxagen")).some(
94961
+ return readdirSync15(join68(root, ".oxagen")).some(
94565
94962
  (name) => name !== "workspace.json"
94566
94963
  );
94567
94964
  } catch {
@@ -94570,21 +94967,21 @@ function oxagenPresent(root) {
94570
94967
  }
94571
94968
  function symlinkState(root) {
94572
94969
  try {
94573
- if (!lstatSync12(join67(root, ".stella")).isDirectory()) return "none";
94970
+ if (!lstatSync12(join68(root, ".stella")).isDirectory()) return "none";
94574
94971
  } catch {
94575
94972
  return "none";
94576
94973
  }
94577
94974
  let oxagenReal;
94578
94975
  try {
94579
- oxagenReal = realpathSync10(join67(root, ".oxagen"));
94976
+ oxagenReal = realpathSync11(join68(root, ".oxagen"));
94580
94977
  } catch {
94581
94978
  return "missing";
94582
94979
  }
94583
94980
  for (const link of STELLA_LINKS) {
94584
- const at2 = join67(root, link);
94981
+ const at2 = join68(root, link);
94585
94982
  try {
94586
94983
  if (!lstatSync12(at2).isSymbolicLink()) return "missing";
94587
- const target2 = realpathSync10(at2);
94984
+ const target2 = realpathSync11(at2);
94588
94985
  if (target2 !== oxagenReal && !target2.startsWith(oxagenReal + sep11)) {
94589
94986
  return "missing";
94590
94987
  }
@@ -94595,7 +94992,7 @@ function symlinkState(root) {
94595
94992
  return "linked";
94596
94993
  }
94597
94994
  function machineId(configDir = getConfigDir()) {
94598
- const file = join67(configDir, MACHINE_ID_FILE);
94995
+ const file = join68(configDir, MACHINE_ID_FILE);
94599
94996
  let secret = null;
94600
94997
  try {
94601
94998
  if (existsSync31(file)) {
@@ -94666,7 +95063,7 @@ async function reportWorkingCopy(opts) {
94666
95063
  }
94667
95064
  function realpathOr2(path2) {
94668
95065
  try {
94669
- return realpathSync10(path2);
95066
+ return realpathSync11(path2);
94670
95067
  } catch {
94671
95068
  return resolve25(path2);
94672
95069
  }
@@ -94677,12 +95074,12 @@ async function ensureWorkspaceLinkIgnored(root) {
94677
95074
  const topDir = resolve25(top);
94678
95075
  const entry2 = relative9(
94679
95076
  topDir,
94680
- join67(realpathOr2(root), ".oxagen", "workspace.json")
95077
+ join68(realpathOr2(root), ".oxagen", "workspace.json")
94681
95078
  ).split(sep11).join("/");
94682
95079
  if (entry2.startsWith("../")) return null;
94683
95080
  const rule = await git4(topDir, ["check-ignore", "--no-index", "-v", entry2]);
94684
95081
  if (rule !== null) return null;
94685
- const gitignore = join67(resolve25(top), ".gitignore");
95082
+ const gitignore = join68(resolve25(top), ".gitignore");
94686
95083
  let existing = "";
94687
95084
  try {
94688
95085
  existing = readFileSync31(gitignore, "utf8");
@@ -94841,7 +95238,7 @@ Waiting for GitHub authorization (timeout: ${Math.round(poll.timeoutMs / 6e4)} m
94841
95238
  return null;
94842
95239
  }
94843
95240
  process.stdout.write(`
94844
- GitHub connected! Fetching repositories...
95241
+ GitHub connected. Fetching repositories...
94845
95242
  `);
94846
95243
  let installations;
94847
95244
  try {
@@ -95200,14 +95597,14 @@ import {
95200
95597
  mkdirSync as mkdirSync14,
95201
95598
  readFileSync as readFileSync32,
95202
95599
  readdirSync as readdirSync16,
95203
- realpathSync as realpathSync11,
95600
+ realpathSync as realpathSync12,
95204
95601
  rmSync as rmSync14,
95205
95602
  rmdirSync as rmdirSync7
95206
95603
  } from "node:fs";
95207
95604
  import {
95208
- dirname as dirname37,
95605
+ dirname as dirname38,
95209
95606
  isAbsolute as isAbsolute18,
95210
- join as join68,
95607
+ join as join69,
95211
95608
  parse as parsePath2,
95212
95609
  posix as posix5,
95213
95610
  sep as sep12
@@ -95232,7 +95629,7 @@ function checkSteeringPath(path2) {
95232
95629
  }
95233
95630
  const normalized = posix5.normalize(path2);
95234
95631
  if (normalized !== path2 || normalized.split("/").some((s2) => s2 === ".." || s2 === ".")) {
95235
- return { ok: false, reason: "not a canonical path" };
95632
+ return { ok: false, reason: "has a . or .. part or a double slash" };
95236
95633
  }
95237
95634
  if (!normalized.startsWith(`${OXAGEN_DIR}/`)) {
95238
95635
  return { ok: false, reason: "outside .oxagen/" };
@@ -95320,14 +95717,14 @@ function findLinkedRoot(start) {
95320
95717
  } catch {
95321
95718
  }
95322
95719
  if (dir === root) return null;
95323
- const parent = dirname37(dir);
95720
+ const parent = dirname38(dir);
95324
95721
  if (parent === dir) return null;
95325
95722
  dir = parent;
95326
95723
  }
95327
95724
  }
95328
95725
  function fsReader(root) {
95329
95726
  return (path2) => {
95330
- const abs = join68(root, ...path2.split("/"));
95727
+ const abs = join69(root, ...path2.split("/"));
95331
95728
  try {
95332
95729
  const st = lstatSync13(abs);
95333
95730
  if (!st.isFile()) return Buffer.from(`\0not-a-file:${abs}`);
@@ -95338,14 +95735,14 @@ function fsReader(root) {
95338
95735
  };
95339
95736
  }
95340
95737
  function assertInsideOxagen(root, path2) {
95341
- const oxagenAbs = join68(root, OXAGEN_DIR);
95738
+ const oxagenAbs = join69(root, OXAGEN_DIR);
95342
95739
  let oxagenReal;
95343
95740
  try {
95344
- oxagenReal = realpathSync11(oxagenAbs);
95741
+ oxagenReal = realpathSync12(oxagenAbs);
95345
95742
  } catch {
95346
95743
  return;
95347
95744
  }
95348
- const abs = join68(root, ...path2.split("/"));
95745
+ const abs = join69(root, ...path2.split("/"));
95349
95746
  try {
95350
95747
  if (lstatSync13(abs).isSymbolicLink()) {
95351
95748
  throw new Error(
@@ -95355,11 +95752,11 @@ function assertInsideOxagen(root, path2) {
95355
95752
  } catch (err2) {
95356
95753
  if (err2.code !== "ENOENT") throw err2;
95357
95754
  }
95358
- let dir = dirname37(abs);
95755
+ let dir = dirname38(abs);
95359
95756
  for (; ; ) {
95360
95757
  let real = null;
95361
95758
  try {
95362
- real = realpathSync11(dir);
95759
+ real = realpathSync12(dir);
95363
95760
  } catch {
95364
95761
  real = null;
95365
95762
  }
@@ -95369,14 +95766,14 @@ function assertInsideOxagen(root, path2) {
95369
95766
  }
95370
95767
  return;
95371
95768
  }
95372
- const parent = dirname37(dir);
95769
+ const parent = dirname38(dir);
95373
95770
  if (parent === dir) return;
95374
95771
  dir = parent;
95375
95772
  }
95376
95773
  }
95377
95774
  function pruneEmptyDirs(root, path2) {
95378
- const stop = join68(root, OXAGEN_DIR);
95379
- let dir = dirname37(join68(root, ...path2.split("/")));
95775
+ const stop = join69(root, OXAGEN_DIR);
95776
+ let dir = dirname38(join69(root, ...path2.split("/")));
95380
95777
  while (dir.startsWith(stop + sep12)) {
95381
95778
  try {
95382
95779
  if (readdirSync16(dir).length > 0) return;
@@ -95384,19 +95781,19 @@ function pruneEmptyDirs(root, path2) {
95384
95781
  } catch {
95385
95782
  return;
95386
95783
  }
95387
- dir = dirname37(dir);
95784
+ dir = dirname38(dir);
95388
95785
  }
95389
95786
  }
95390
95787
  function applyPlan(root, plan) {
95391
95788
  for (const w of plan.writes) assertInsideOxagen(root, w.path);
95392
95789
  for (const d of plan.deletes) assertInsideOxagen(root, d);
95393
95790
  for (const w of plan.writes) {
95394
- const abs = join68(root, ...w.path.split("/"));
95395
- mkdirSync14(dirname37(abs), { recursive: true });
95791
+ const abs = join69(root, ...w.path.split("/"));
95792
+ mkdirSync14(dirname38(abs), { recursive: true });
95396
95793
  atomicWriteFileSync(abs, w.content);
95397
95794
  }
95398
95795
  for (const d of plan.deletes) {
95399
- rmSync14(join68(root, ...d.split("/")), { force: true });
95796
+ rmSync14(join69(root, ...d.split("/")), { force: true });
95400
95797
  pruneEmptyDirs(root, d);
95401
95798
  }
95402
95799
  }
@@ -97282,7 +97679,7 @@ var init_lock = __esm({
97282
97679
  "source.registry_type: npm, pypi, oci, or nuget."
97283
97680
  ),
97284
97681
  digest: sha256Schema2.describe(
97285
- "For oci, the image's manifest digest. For pypi, the SHA-256 of file. For the others, the SHA-256 of the package archive."
97682
+ "For oci, the SHA-256 of the image's manifest. For pypi, the SHA-256 of file. For the others, the SHA-256 of the package archive."
97286
97683
  ),
97287
97684
  file: pypiLockFileSchema.optional().describe("For pypi: the one file of the release the launch installs.")
97288
97685
  }),
@@ -97610,20 +98007,20 @@ var init_envelope3 = __esm({
97610
98007
  );
97611
98008
  envelopeSignatureSchema2 = external_exports.object({
97612
98009
  key_id: external_exports.string().regex(/^[0-9a-f]{16}$/, "a key id is 16 lowercase hex characters").describe(
97613
- "The first 8 bytes of the SHA-256 of the signing public key, in hex."
98010
+ "The first 8 bytes of the SHA-256 of the public key that locks the envelope, in hex."
97614
98011
  ),
97615
98012
  alg: external_exports.literal("ed25519"),
97616
98013
  sig: external_exports.string().regex(
97617
98014
  /^[A-Za-z0-9+/]{86}==$/,
97618
- "an Ed25519 signature is 64 bytes in padded base64"
98015
+ "an Ed25519 lock is 64 bytes in padded base64"
97619
98016
  ).describe(
97620
- "The signature over the envelope's RFC 8785 bytes without its signature field."
98017
+ "The lock over the envelope's RFC 8785 bytes without its `signature` field."
97621
98018
  )
97622
- }).strict().describe("The cloud gateway's signature.");
98019
+ }).strict().describe("The cloud gateway's lock on the envelope.");
97623
98020
  envelopeDeadlineSchema = external_exports.number().int().min(1).max(3e5).optional();
97624
98021
  machineIdSchema2 = external_exports.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "not a machine id");
97625
98022
  issuedAtSchema = instantSchema2.describe(
97626
- "When the cloud gateway signed the envelope."
98023
+ "When the cloud gateway locked the envelope."
97627
98024
  );
97628
98025
  expiresAtSchema = instantSchema2.describe(
97629
98026
  `When the envelope stops being valid: after issued_at, and at most ${ENVELOPE_TTL_MAX_MS2 / 1e3} seconds after it.`
@@ -97770,7 +98167,7 @@ var init_relay_envelope = __esm({
97770
98167
  ),
97771
98168
  credential: relayCredentialSchema.optional(),
97772
98169
  signature: envelopeSignatureSchema2
97773
- }).strict().describe("One request the cloud gateway decided and signed for a relay."),
98170
+ }).strict().describe("One request the cloud gateway decided and locked for a relay."),
97774
98171
  [expiryCheck, mutualTlsCheck]
97775
98172
  );
97776
98173
  }
@@ -97801,7 +98198,7 @@ var init_local_call_envelope = __esm({
97801
98198
  "The tool's definition hash in the lock."
97802
98199
  ),
97803
98200
  package_digest: sha256Schema2.describe(
97804
- "The lock's digest of the package or binary. The local gateway refuses a command that does not match."
98201
+ "The lock's hash of the package or binary. The local gateway refuses a command that does not match."
97805
98202
  ),
97806
98203
  arguments_hash: sha256Schema2.describe(
97807
98204
  "SHA-256 over the RFC 8785 form of the upstream arguments, after the input was shaped."
@@ -97820,7 +98217,7 @@ var init_local_call_envelope = __esm({
97820
98217
  expires_at: expiresAtSchema,
97821
98218
  signature: envelopeSignatureSchema2
97822
98219
  }).strict().describe(
97823
- "One call to a local server that the cloud gateway decided and signed."
98220
+ "One call to a local server that the cloud gateway decided and locked."
97824
98221
  ),
97825
98222
  [expiryCheck]
97826
98223
  );
@@ -97840,7 +98237,7 @@ var init_local_discovery_envelope = __esm({
97840
98237
  external_exports.object({
97841
98238
  schema: external_exports.literal("local-discovery-envelope/v1"),
97842
98239
  package_digest: sha256Schema2.describe(
97843
- "The lock's digest of the package or binary. The local gateway refuses a command that does not match."
98240
+ "The lock's hash of the package or binary. The local gateway refuses a command that does not match."
97844
98241
  ),
97845
98242
  launch_digest: sha256Schema2.describe(
97846
98243
  "SHA-256 over the RFC 8785 form of the launch's command, args with each ${NAME} unfilled, and env names. The local gateway refuses a launch that does not match."
@@ -97856,7 +98253,7 @@ var init_local_discovery_envelope = __esm({
97856
98253
  expires_at: expiresAtSchema,
97857
98254
  signature: envelopeSignatureSchema2
97858
98255
  }).strict().describe(
97859
- "One discovery of a local server's tools that the cloud gateway decided and signed."
98256
+ "One discovery of a local server's tools that the cloud gateway decided and locked."
97860
98257
  ),
97861
98258
  [expiryCheck]
97862
98259
  );
@@ -139514,9 +139911,9 @@ import {
139514
139911
  mkdirSync as mkdirSync15,
139515
139912
  readFileSync as readFileSync33,
139516
139913
  readlinkSync as readlinkSync4,
139517
- statSync as statSync19
139914
+ statSync as statSync20
139518
139915
  } from "node:fs";
139519
- import { dirname as dirname38, isAbsolute as isAbsolute19, join as join69, relative as relative10, resolve as resolve27, sep as sep13 } from "node:path";
139916
+ import { dirname as dirname39, isAbsolute as isAbsolute19, join as join70, relative as relative10, resolve as resolve27, sep as sep13 } from "node:path";
139520
139917
  function cloneRepoKind(root) {
139521
139918
  const out = git5(root, ["remote", "get-url", "origin"]);
139522
139919
  const url = out?.toString("utf8").trim() ?? "";
@@ -139556,7 +139953,7 @@ function commitOf2(root, ref) {
139556
139953
  return sha2.length > 0 ? sha2 : null;
139557
139954
  }
139558
139955
  function readWorkingFile(root, path2) {
139559
- const abs = join69(root, ...path2.split("/"));
139956
+ const abs = join70(root, ...path2.split("/"));
139560
139957
  try {
139561
139958
  const stat7 = lstatSync14(abs);
139562
139959
  if (stat7.isSymbolicLink()) return readlinkSync4(abs, "utf8");
@@ -139635,14 +140032,14 @@ function chooseBase(root, ref) {
139635
140032
  }
139636
140033
  function isFile(path2) {
139637
140034
  try {
139638
- return statSync19(path2).isFile();
140035
+ return statSync20(path2).isFile();
139639
140036
  } catch {
139640
140037
  return false;
139641
140038
  }
139642
140039
  }
139643
140040
  function isDir(path2) {
139644
140041
  try {
139645
- return statSync19(path2).isDirectory();
140042
+ return statSync20(path2).isDirectory();
139646
140043
  } catch {
139647
140044
  return false;
139648
140045
  }
@@ -139650,10 +140047,10 @@ function isDir(path2) {
139650
140047
  function findSteeringRoot(start) {
139651
140048
  let dir = resolve27(start);
139652
140049
  for (; ; ) {
139653
- if (isFile(join69(dir, WORKSPACE_TOML_PATH)) || isFile(join69(dir, AGENTS_MD_PATH)) && isDir(join69(dir, STEERING_DIR))) {
140050
+ if (isFile(join70(dir, WORKSPACE_TOML_PATH)) || isFile(join70(dir, AGENTS_MD_PATH)) && isDir(join70(dir, STEERING_DIR))) {
139654
140051
  return dir;
139655
140052
  }
139656
- const parent = dirname38(dir);
140053
+ const parent = dirname39(dir);
139657
140054
  if (parent === dir) return null;
139658
140055
  dir = parent;
139659
140056
  }
@@ -139730,7 +140127,7 @@ function cacheFile(cacheDir, root) {
139730
140127
  key: token === void 0 ? null : createHash23("sha256").update(token).digest("hex").slice(0, 16)
139731
140128
  };
139732
140129
  const key = createHash23("sha256").update(JSON.stringify([root, identity])).digest("hex").slice(0, 32);
139733
- return join69(cacheDir, `${key}.json`);
140130
+ return join70(cacheDir, `${key}.json`);
139734
140131
  }
139735
140132
  function readCache(file, now) {
139736
140133
  let entry2;
@@ -139758,7 +140155,7 @@ async function publishedInputs(root, deps, refresh, out) {
139758
140155
  }
139759
140156
  if (file !== null) {
139760
140157
  try {
139761
- mkdirSync15(dirname38(file), { recursive: true });
140158
+ mkdirSync15(dirname39(file), { recursive: true });
139762
140159
  atomicWriteFileSync(
139763
140160
  file,
139764
140161
  JSON.stringify({
@@ -139844,7 +140241,7 @@ function defaultDeps2() {
139844
140241
  return {
139845
140242
  fetchPublished: fetchSteeringIndex,
139846
140243
  cedar: cedarHooks,
139847
- cacheDir: join69(getConfigDir(), "cache", "steering-check"),
140244
+ cacheDir: join70(getConfigDir(), "cache", "steering-check"),
139848
140245
  now: () => Date.now()
139849
140246
  };
139850
140247
  }
@@ -144196,7 +144593,7 @@ var init_src9 = __esm({
144196
144593
 
144197
144594
  // src/commands/codegraph-upload/files.ts
144198
144595
  import { readdir as readdir5, stat as stat5 } from "node:fs/promises";
144199
- import { join as join70, relative as relative11, sep as sep14 } from "node:path";
144596
+ import { join as join71, relative as relative11, sep as sep14 } from "node:path";
144200
144597
  function hasGlobChars(pattern) {
144201
144598
  return /[*?[\]{}]/.test(pattern);
144202
144599
  }
@@ -144208,7 +144605,7 @@ async function walk(root, dir, out) {
144208
144605
  const entries2 = await readdir5(dir, { withFileTypes: true });
144209
144606
  for (const entry2 of entries2) {
144210
144607
  if (entry2.isSymbolicLink()) continue;
144211
- const full = join70(dir, entry2.name);
144608
+ const full = join71(dir, entry2.name);
144212
144609
  if (entry2.isDirectory()) {
144213
144610
  if (!SKIP_DIRS.has(entry2.name)) await walk(root, full, out);
144214
144611
  } else if (entry2.isFile()) {
@@ -144220,7 +144617,7 @@ async function expandPattern(root, pattern) {
144220
144617
  const wanted = normalize3(pattern.trim());
144221
144618
  if (!hasGlobChars(wanted)) {
144222
144619
  try {
144223
- const info = await stat5(join70(root, wanted));
144620
+ const info = await stat5(join71(root, wanted));
144224
144621
  return info.isFile() ? [wanted] : [];
144225
144622
  } catch {
144226
144623
  return [];
@@ -144371,7 +144768,7 @@ var init_token = __esm({
144371
144768
  });
144372
144769
 
144373
144770
  // src/commands/codegraph-upload/run.ts
144374
- import { join as join71 } from "node:path";
144771
+ import { join as join72 } from "node:path";
144375
144772
  function addDropped(into, more) {
144376
144773
  into.sensitiveValues += more.sensitiveValues;
144377
144774
  into.secretData += more.secretData;
@@ -144389,7 +144786,7 @@ async function uploadOne(deps, config, token, group, path2, totals2) {
144389
144786
  const label2 = `${group.kind}/${group.source} ${path2}`;
144390
144787
  let bytes;
144391
144788
  try {
144392
- bytes = await deps.readFile(join71(deps.cwd, path2));
144789
+ bytes = await deps.readFile(join72(deps.cwd, path2));
144393
144790
  } catch (error) {
144394
144791
  totals2.failed += 1;
144395
144792
  deps.log(`error: ${label2}: cannot read the file: ${error.message}`);
@@ -144847,7 +145244,7 @@ var init_usage = __esm({
144847
145244
  "Oxagen CLI collects anonymous usage telemetry (command names, durations,",
144848
145245
  "coarse success/error categories, OS/arch) to improve the product. It never",
144849
145246
  "collects code, prompts, file contents, file paths, model slugs, or",
144850
- "personal data \u2014 see TELEMETRY.md for the exact field list.",
145247
+ "personal data. See TELEMETRY.md for the exact field list.",
144851
145248
  "",
144852
145249
  "Opt out anytime: `oxagen telemetry off`, or set OXAGEN_TELEMETRY=0 /",
144853
145250
  "DO_NOT_TRACK=1. This notice only prints once.",
@@ -144878,7 +145275,7 @@ function telemetryStatus(writer = stdoutWriter) {
144878
145275
  status2,
144879
145276
  () => [
144880
145277
  `Telemetry: ${enabled ? "enabled" : "disabled"}`,
144881
- `Install id: ${installId ?? "(not yet generated \u2014 created on first command)"}`,
145278
+ `Install id: ${installId ?? "(not yet generated; created on first command)"}`,
144882
145279
  `Ingest endpoint: ${ingestEndpoint}`,
144883
145280
  "See TELEMETRY.md for the full disclosure."
144884
145281
  ].join("\n")
@@ -144893,7 +145290,7 @@ function telemetryOff(writer = stdoutWriter) {
144893
145290
  const config = readConfig();
144894
145291
  writeConfig({ telemetry: { ...config.telemetry, enabled: false } });
144895
145292
  createOutput({}, writer).info(
144896
- "\u2713 Telemetry disabled \u2014 no usage data will be sent."
145293
+ "\u2713 Telemetry disabled. No usage data will be sent."
144897
145294
  );
144898
145295
  }
144899
145296
  function isSubcommand(value) {
@@ -144983,7 +145380,7 @@ function makeErrorHtml(message) {
144983
145380
  <html lang="en">
144984
145381
  <head>
144985
145382
  <meta charset="utf-8">
144986
- <title>Oxagen \u2014 Login failed</title>
145383
+ <title>Oxagen: Login failed</title>
144987
145384
  <style>
144988
145385
  body { font-family: system-ui, sans-serif; display: flex; justify-content: center;
144989
145386
  align-items: center; min-height: 100vh; margin: 0; background: #f4f4f5; }
@@ -145680,7 +146077,7 @@ async function agentStatus2(agent, opts = {}, writer = stdoutWriter) {
145680
146077
  return;
145681
146078
  }
145682
146079
  const { identity } = result2;
145683
- writer.write(`${identity.name} (${identity.slug}) \u2014 ${identity.status}`);
146080
+ writer.write(`${identity.name} (${identity.slug}): ${identity.status}`);
145684
146081
  writer.write(` id ${identity.id}`);
145685
146082
  writer.write(` agent key ${identity.agentKey ?? "\u2014"}`);
145686
146083
  writer.write(` harness ${identity.harness}`);
@@ -146126,7 +146523,7 @@ async function routerPreview(prompt, opts = {}, writer = stdoutWriter) {
146126
146523
  writer.write("");
146127
146524
  if (result2.candidates.length === 0) {
146128
146525
  writer.write(
146129
- "No observed candidates for this class \u2014 deterministic fallback used."
146526
+ "No observed models for this class. Deterministic fallback used."
146130
146527
  );
146131
146528
  return;
146132
146529
  }
@@ -146383,7 +146780,7 @@ async function handleSecretImport(opts, writer = stdoutWriter) {
146383
146780
  const { rows, committed } = await apiPostOrThrow("secret/import-env", { text: text5, environmentId, commit: !!opts.yes });
146384
146781
  const newCount = rows.filter((r) => r.isNewKey).length;
146385
146782
  writer.write(
146386
- `${committed ? "imported" : "preview"} \u2014 ${rows.length} parsed (${newCount} new, ${rows.length - newCount} existing):`
146783
+ `${committed ? "imported" : "preview"}: ${rows.length} parsed (${newCount} new, ${rows.length - newCount} existing):`
146387
146784
  );
146388
146785
  printTable(
146389
146786
  ["", "KEY", "TARGET", "SENS", "STATE"],
@@ -146616,7 +147013,7 @@ function addHostWrapCommands(parent) {
146616
147013
  function buildProgram() {
146617
147014
  const program2 = new Command();
146618
147015
  program2.name("oxagen").description(
146619
- "Oxagen governance CLI \u2014 spend, traces, grounding, credentials, and audit"
147016
+ "Oxagen governance CLI: spend, traces, grounding, credentials, and audit"
146620
147017
  ).version(version).option(
146621
147018
  "-m, --model <slug>",
146622
147019
  "Model slug for subcommands that price or filter by model (e.g. cost)"
@@ -146641,7 +147038,7 @@ function buildProgram() {
146641
147038
  "github",
146642
147039
  "Route repository Git requests through the host's credential custody"
146643
147040
  ],
146644
- ["arp", "Capture and prepare local Agent Run Protocol checkpoints"]
147041
+ ["arp", "Capture and prepare local Agent Run Protocol save points"]
146645
147042
  ];
146646
147043
  for (const [name, description] of recorderCommands) {
146647
147044
  program2.command(name, { hidden: true }).description(description).helpOption(false).allowUnknownOption().allowExcessArguments().action(async () => {
@@ -146657,17 +147054,17 @@ function buildProgram() {
146657
147054
  handleCost2(merged);
146658
147055
  });
146659
147056
  const budgetCmd = program2.command("budget").description(
146660
- "Hard period-to-date spend ceilings that gate agent runs \u2014 org + workspace"
147057
+ "Hard period-to-date spend ceilings that gate agent runs (org + workspace)"
146661
147058
  );
146662
147059
  budgetCmd.command("show").description("Show configured spend ceilings with their live burn").option("--json", "Output JSON").action(async (opts) => {
146663
147060
  const { budgetShow: budgetShow2 } = await Promise.resolve().then(() => (init_budget2(), budget_exports));
146664
147061
  await budgetShow2(opts);
146665
147062
  });
146666
147063
  budgetCmd.command("set").description(
146667
- "Set (create or replace) a spend ceiling \u2014 Owner/Admin/Billing only"
147064
+ "Set (create or replace) a spend ceiling (Owner/Admin/Billing only)"
146668
147065
  ).requiredOption("--scope <scope>", "org | workspace").requiredOption("--period <period>", "monthly | rolling").requiredOption("--limit <usd>", "Hard USD ceiling (> 0)").option(
146669
147066
  "--window-days <n>",
146670
- "Trailing window in days \u2014 required for --period rolling, omit for monthly"
147067
+ "Trailing window in days: required for --period rolling, omit for monthly"
146671
147068
  ).option(
146672
147069
  "--enabled <bool>",
146673
147070
  "Whether the ceiling is enforced (true/false)",
@@ -146699,7 +147096,7 @@ function buildProgram() {
146699
147096
  }
146700
147097
  );
146701
147098
  const priceCmd = program2.command("price").description(
146702
- "The organization's negotiated rates in the price book \u2014 what runs are billed at"
147099
+ "The organization's negotiated rates in the price book: what runs are billed at"
146703
147100
  );
146704
147101
  priceCmd.command("list").description(
146705
147102
  "Read current prices and optionally scheduled negotiated rates"
@@ -146713,7 +147110,7 @@ function buildProgram() {
146713
147110
  }
146714
147111
  );
146715
147112
  priceCmd.command("set").description(
146716
- "Set a negotiated rate for one model and token class \u2014 Owner/Admin/Billing only"
147113
+ "Set a negotiated rate for one model and token class (Owner/Admin/Billing only)"
146717
147114
  ).requiredOption("--provider <provider>", "Provider, e.g. anthropic").requiredOption("--model <model>", "Model id, e.g. claude-sonnet-5").requiredOption(
146718
147115
  "--token-class <class>",
146719
147116
  "input_uncached | cache_read | cache_write_5m | cache_write_1h | output | reasoning | server_tool_request | embedding_input | rerank | image | video_second"
@@ -146737,7 +147134,7 @@ function buildProgram() {
146737
147134
  await priceSet2(opts);
146738
147135
  });
146739
147136
  priceCmd.command("remove").description(
146740
- "End a negotiated rate so the model returns to the list price \u2014 Owner/Admin/Billing only"
147137
+ "End a negotiated rate so the model returns to the list price (Owner/Admin/Billing only)"
146741
147138
  ).requiredOption("--provider <provider>", "Provider, e.g. anthropic").requiredOption("--model <model>", "Model id, e.g. claude-sonnet-5").requiredOption("--token-class <class>", "The token class to end").option("--region <region>", "Region the rate applies to; omit for any").option(
146742
147139
  "--at <instant>",
146743
147140
  "RFC 3339 instant the rate stops applying; omit for now"
@@ -146820,23 +147217,23 @@ function buildProgram() {
146820
147217
  }
146821
147218
  );
146822
147219
  const contextCmd = program2.command("context").description(
146823
- "Steering: record a proposal on a lineage, or revert a merged one"
147220
+ "Steering: record a suggestion for a steering record, or revert a merged one"
146824
147221
  );
146825
147222
  contextCmd.command("propose").description(
146826
- "Record a proposal (the record it should become, why); its steering PR is opened and merged in Oxagen"
147223
+ "Record a suggestion (the record it should become, why); its steering PR is opened and merged in Oxagen"
146827
147224
  ).requiredOption(
146828
147225
  "--lineage <id>",
146829
- "The lineage id (the file stem under .oxagen/rules/)"
147226
+ "The record ID (the file stem under .oxagen/rules/)"
146830
147227
  ).requiredOption(
146831
147228
  "--kind <kind>",
146832
147229
  "rule | constraint | procedure | fact | memory | preference"
146833
- ).requiredOption("--force <force>", "must | should | may | info").requiredOption("--scope <scope>", "workspace | repository").requiredOption("--statement <text>", "The single-sentence claim").requiredOption("--rationale <text>", "Why the record should be published").option("--effect <effect>", "require | forbid \u2014 a constraint only").option("--json", "Output JSON").action(
147230
+ ).requiredOption("--force <force>", "must | should | may | info").requiredOption("--scope <scope>", "workspace | repository").requiredOption("--statement <text>", "The single-sentence claim").requiredOption("--rationale <text>", "Why the record should be published").option("--effect <effect>", "require | forbid (a constraint only)").option("--json", "Output JSON").action(
146834
147231
  async (opts) => {
146835
147232
  const { contextPropose: contextPropose2 } = await Promise.resolve().then(() => (init_context4(), context_exports));
146836
147233
  await contextPropose2(opts);
146837
147234
  }
146838
147235
  );
146839
- contextCmd.command("revert <proposalId>").description(
147236
+ contextCmd.command("revert <suggestionId>").description(
146840
147237
  "Open a steering PR that undoes a merged one (revert_steering_pr); it merges after its own review"
146841
147238
  ).option("--json", "Output JSON").action(async (proposalId, opts) => {
146842
147239
  const { contextRevert: contextRevert2 } = await Promise.resolve().then(() => (init_context4(), context_exports));
@@ -146984,8 +147381,8 @@ function buildProgram() {
146984
147381
  await steeringPromote2(findingId, opts);
146985
147382
  });
146986
147383
  steeringCmd.command("restore-block").argument(
146987
- "<proposal-id>",
146988
- "The prp_\u2026 proposal whose steering PR holds the file"
147384
+ "<suggestion-id>",
147385
+ "The prp_\u2026 suggestion whose steering PR holds the file"
146989
147386
  ).argument("<path>", "AGENTS.md, CLAUDE.md, or README.md").description(
146990
147387
  "Restore Oxagen's managed block in one file of an open steering PR, as one commit from the production branch"
146991
147388
  ).option("--json", "Output JSON").action(
@@ -147002,7 +147399,7 @@ function buildProgram() {
147002
147399
  await toolsMigrate2(opts);
147003
147400
  });
147004
147401
  const runCmd = program2.command("run").description(
147005
- "Start an agent under the contained launcher (`oxagen run -- claude -p <task>`), start a run in its own sandbox (`oxagen run --harness claude --workspace-slug <slug> --repo <owner/name>`), or read a recorded run: its chain and seal, and its signed evidence bundle"
147402
+ "Start an agent under the contained launcher (`oxagen run -- claude -p <task>`), start a run in its own sandbox (`oxagen run --harness claude --workspace-slug <slug> --repo <owner/name>`), or read a recorded run: its chain, Oxagen's lock on it, and its locked evidence bundle"
147006
147403
  ).option("--image <ref>", "The contained image (or OXAGEN_CONTAINED_IMAGE)").option(
147007
147404
  "--workspace <dir>",
147008
147405
  "The repository root to mount at /workspace (default: the current directory). A sandbox run names its workspace with --workspace-slug"
@@ -147072,7 +147469,7 @@ function buildProgram() {
147072
147469
  }
147073
147470
  );
147074
147471
  runCmd.command("chain").description(
147075
- "Show what makes a run's record tamper-evident: the hash rule, the root, the checkpoints, the gaps, and the replay ladder"
147472
+ "Show what makes a run's record tamper-evident: the hash rule, the root, the locks taken along the way, the gaps, and the replay ladder"
147076
147473
  ).argument("<run-id>", "The run's public id (arun_\u2026 or tse_\u2026)").option("--json", "Output JSON").action(async (runId, opts) => {
147077
147474
  const { runChain: runChain2 } = await Promise.resolve().then(() => (init_run4(), run_exports));
147078
147475
  await runChain2(runId, opts);
@@ -147087,7 +147484,7 @@ function buildProgram() {
147087
147484
  "Read one page of a run's transcript: its entries, the count per chip over the whole run, and a search of the kept bodies"
147088
147485
  ).argument("<run-id>", "The run's public id (arun_\u2026 or tse_\u2026)").option("--zoom <zoom>", "turns, steps, or everything", "steps").option(
147089
147486
  "--kinds <kinds>",
147090
- "The chips to keep, comma-separated (thinking,seal)"
147487
+ "The chips to keep, comma-separated (thinking,tools)"
147091
147488
  ).option("--query <words>", "Words to search the entries for, ignoring case").option("--after <cursor>", "The cursor the previous page printed").option("--limit <n>", "Page size, 1 to 500", wholeNumber2(1, 500)).option("--text <text>", "How much of each body to carry: excerpt or full").option("--json", "Output the raw contract payload as JSON").action(
147092
147489
  async (runId, opts) => {
147093
147490
  const { runTranscript: runTranscript2 } = await Promise.resolve().then(() => (init_run4(), run_exports));
@@ -147101,7 +147498,7 @@ function buildProgram() {
147101
147498
  await runContext2(runId, opts);
147102
147499
  });
147103
147500
  runCmd.command("export").description(
147104
- "Queue the signed, offline-verifiable evidence bundle for a sealed run \u2014 Owner/Admin only"
147501
+ "Queue the evidence bundle for a locked run. Oxagen locks the bundle so anyone can check it offline (Owner/Admin only)"
147105
147502
  ).argument("<run-id>", "The run's public id (arun_\u2026 or tse_\u2026)").option("--json", "Output JSON").action(async (runId, opts) => {
147106
147503
  const { runExport: runExport2 } = await Promise.resolve().then(() => (init_run4(), run_exports));
147107
147504
  await runExport2(runId, opts);
@@ -147116,7 +147513,7 @@ function buildProgram() {
147116
147513
  await runExportStatus2(exportId, opts);
147117
147514
  });
147118
147515
  runCmd.command("download").description(
147119
- "Download a ready run export and check its sha256 against the recorded digest"
147516
+ "Download a ready run export and check its sha256 against the recorded hash"
147120
147517
  ).argument(
147121
147518
  "<export-id>",
147122
147519
  "The export id `oxagen run export` printed (rexp_\u2026)"
@@ -147281,13 +147678,13 @@ function buildProgram() {
147281
147678
  )
147282
147679
  );
147283
147680
  program2.command("verify").description(
147284
- "Check a run export bundle offline: each frame's digest and link, the Merkle root, and each signature"
147681
+ "Check a run export bundle offline: each frame's hash and link, the Merkle root, and each lock"
147285
147682
  ).argument("<bundle>", "The bundle's .zip file or its extracted directory").option("--json", "Output the verification as JSON").action(async (bundle2, opts) => {
147286
147683
  const { verifyBundle: verifyBundle4 } = await Promise.resolve().then(() => (init_verify2(), verify_exports));
147287
147684
  await verifyBundle4(bundle2, opts);
147288
147685
  });
147289
147686
  program2.command("attention").description(
147290
- "List what waits on you in this workspace: approvals and questions on your runs, work orders in review, ready work items assigned to you, and steering proposals"
147687
+ "List what waits on you in this workspace: approvals and questions on your runs, work orders in review, ready work items assigned to you, and steering suggestions"
147291
147688
  ).option(
147292
147689
  "--state <state>",
147293
147690
  "open lists what waits; resolved lists what was answered",
@@ -147373,7 +147770,7 @@ function buildProgram() {
147373
147770
  ).option(
147374
147771
  "--harness <harness>",
147375
147772
  "Only memories this harness keeps: claude-code, codex, cursor, stella, or claude-desktop"
147376
- ).option("--agent <lineage>", "Only memories this agent wrote").option(
147773
+ ).option("--agent <record-id>", "Only memories this agent wrote").option(
147377
147774
  "--repository <repo>",
147378
147775
  "Only memories scoped to this repository, such as github.com/acme/api"
147379
147776
  ).option(
@@ -147598,16 +147995,16 @@ function buildProgram() {
147598
147995
  }
147599
147996
  );
147600
147997
  program2.command("telemetry").description(
147601
- "Inspect or control anonymous CLI usage telemetry (on by default \u2014 see TELEMETRY.md)"
147998
+ "Inspect or control anonymous CLI usage telemetry (on by default; see TELEMETRY.md)"
147602
147999
  ).argument("[subcommand]", "on | off | status (default: status)").action(async (subcommand) => {
147603
148000
  const { handleTelemetry: handleTelemetry2 } = await Promise.resolve().then(() => (init_telemetry(), telemetry_exports));
147604
148001
  handleTelemetry2(subcommand);
147605
148002
  });
147606
148003
  program2.command("login").description(
147607
- "Authenticate the CLI \u2014 opens a browser by default (interactive). Use --token for CI/headless."
148004
+ "Authenticate the CLI. Opens a browser by default (interactive). Use --token for CI/headless."
147608
148005
  ).option(
147609
148006
  "--token <token>",
147610
- "Platform API token \u2014 skips browser login (CI/headless)"
148007
+ "Platform API token: skips browser login (CI/headless)"
147611
148008
  ).option(
147612
148009
  "--org <slug>",
147613
148010
  "Organization slug; with a saved session and no --token, rescopes the default without a browser"
@@ -147670,7 +148067,7 @@ function buildProgram() {
147670
148067
  "[agent]",
147671
148068
  "An agent id or slug. Omit it to unenroll this machine instead"
147672
148069
  ).description(
147673
- "With an agent: revoke its live host enrollments, or one host with --host \u2014 Owner/Admin only. Without one: remove this machine's hooks and service, revoke its enrollment, delete its host key"
148070
+ "With an agent: revoke its live host enrollments, or one host with --host (Owner/Admin only). Without one: remove this machine's hooks and service, revoke its enrollment, delete its host key"
147674
148071
  ).option("--host <tch_id>", "With an agent: only this host").option("--reason <text>", "Recorded on the host and in the revoke command").option("--json", "With an agent: output JSON").option(
147675
148072
  "--yes",
147676
148073
  "With an agent and no --host: revoke every live host without asking"
@@ -147893,7 +148290,7 @@ function buildProgram() {
147893
148290
  await handleEnvSetDefault2(idOrSlug);
147894
148291
  });
147895
148292
  const routerCmd = program2.command("router").description(
147896
- "Verified-Outcome Market Router \u2014 learned, economic model routing"
148293
+ "Verified-Outcome Market Router: learned, economic model routing"
147897
148294
  );
147898
148295
  routerCmd.command("preview <prompt>").description("Dry-run the routing decision for a prompt (changes nothing)").option("--files <n>", "Expected number of files touched", wholeNumber2(0)).option("--cross-package", "The task crosses package boundaries").option("--task-class <class>", "Override the derived task class").option("--json", "Output JSON").action(
147899
148296
  async (prompt, opts) => {
@@ -147906,7 +148303,7 @@ function buildProgram() {
147906
148303
  const { routerPolicyGet: routerPolicyGet2 } = await Promise.resolve().then(() => (init_router(), router_exports));
147907
148304
  await routerPolicyGet2(opts);
147908
148305
  });
147909
- routerPolicyCmd.command("set").description("Update the policy (org Owner) \u2014 changes spend behavior").option(
148306
+ routerPolicyCmd.command("set").description("Update the policy, which changes spend behavior (org Owner)").option(
147910
148307
  "--scope <scope>",
147911
148308
  "org | workspace (default workspace)",
147912
148309
  oneOf2(["org", "workspace"])