@outerlayer/cli 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +15 -0
  3. package/dist/agent-setup-RBTEACYU.js +28 -0
  4. package/dist/{artifact-link-cmd-2F47LT7F.js → artifact-link-cmd-AVM2EKTV.js} +4 -3
  5. package/dist/{build-BG2YENGK.js → build-TQ6X5PYN.js} +5 -4
  6. package/dist/build-info.json +1 -1
  7. package/dist/{builder-2D3WSOOY.js → builder-DUI2ZH2H.js} +5 -6
  8. package/dist/{check-5XE7XMC4.js → check-5C4YDZYV.js} +53 -50
  9. package/dist/{chunk-R7PF5OOU.js → chunk-3CWUOFV6.js} +21 -14
  10. package/dist/{chunk-G5NPRL2K.js → chunk-3OFZM4X6.js} +548 -68
  11. package/dist/{chunk-2MNPHL23.js → chunk-47TTLEDX.js} +6 -5
  12. package/dist/{chunk-PLMTLGYH.js → chunk-52NC2FIU.js} +4 -3
  13. package/dist/chunk-6CHIYEZZ.js +564 -0
  14. package/dist/{chunk-TI7B7UEO.js → chunk-AMFWYESY.js} +1 -1
  15. package/dist/{chunk-YRYMNBGQ.js → chunk-ANPNT6PM.js} +2 -1
  16. package/dist/{chunk-YU3VKZ5F.js → chunk-B3UKB46N.js} +6 -6
  17. package/dist/{chunk-JXYVA45C.js → chunk-BMYGAGBJ.js} +1050 -304
  18. package/dist/{chunk-4Q7OMKAT.js → chunk-BQXFBI7T.js} +81 -5
  19. package/dist/chunk-CRB3POP4.js +34 -0
  20. package/dist/{chunk-F47JBIAW.js → chunk-DSF2FWAZ.js} +2 -1
  21. package/dist/{chunk-N5FOE5PS.js → chunk-ECODQ7II.js} +4 -33
  22. package/dist/{chunk-NBGDBTO2.js → chunk-ESC6UR76.js} +6 -5
  23. package/dist/{chunk-HHJDN6AU.js → chunk-ESVW4MJY.js} +1 -1
  24. package/dist/{chunk-42ZI52JW.js → chunk-F4XSVQJ4.js} +4 -3
  25. package/dist/{chunk-LWSJQJC6.js → chunk-FUB7LRUE.js} +7 -7
  26. package/dist/chunk-G2YNJIGF.js +44 -0
  27. package/dist/{chunk-QKFB4K7X.js → chunk-GGOMT6KF.js} +1 -1
  28. package/dist/{chunk-VQYBXPI7.js → chunk-GOBOJMOJ.js} +5 -5
  29. package/dist/{chunk-N6LURUEF.js → chunk-GOSFARMS.js} +1 -1
  30. package/dist/chunk-JBJTC3UU.js +35 -0
  31. package/dist/{chunk-NWQTTSBB.js → chunk-JF42URPU.js} +16 -15
  32. package/dist/{chunk-ADJRGVZC.js → chunk-KDVIU23F.js} +1 -1
  33. package/dist/{chunk-S3NYLI2P.js → chunk-KK4VBOH6.js} +93 -37
  34. package/dist/{chunk-KMDLFI4P.js → chunk-L2USZT6T.js} +1 -1
  35. package/dist/{chunk-WTE3MQML.js → chunk-LXAY4A2G.js} +3 -12
  36. package/dist/{chunk-V7NIVOFD.js → chunk-M2ZWWTWZ.js} +1 -1
  37. package/dist/{chunk-ERI5GBNI.js → chunk-MLAAT4S6.js} +3 -3
  38. package/dist/{chunk-POJMEEJJ.js → chunk-MNTSH4CL.js} +1 -1
  39. package/dist/{chunk-WUYTWNMA.js → chunk-MQJSXHV7.js} +1 -1
  40. package/dist/{chunk-O765JR4W.js → chunk-MTP2QEVO.js} +1 -1
  41. package/dist/{chunk-ZM2IMMYN.js → chunk-N2PXGQRL.js} +9 -1
  42. package/dist/{chunk-J5M7BSJQ.js → chunk-N3CUDFCW.js} +9 -3
  43. package/dist/{chunk-4KSQKQXE.js → chunk-NACDBXUG.js} +19 -15
  44. package/dist/{chunk-ONKJUM6R.js → chunk-NL4XPC7W.js} +1 -1
  45. package/dist/{chunk-WVUIRTWA.js → chunk-QQM2UJ6T.js} +31 -26
  46. package/dist/{chunk-KG5ECZGJ.js → chunk-RAZTWYZN.js} +10 -9
  47. package/dist/{chunk-4NPZVMJU.js → chunk-S26M3YBJ.js} +60 -4
  48. package/dist/{chunk-UGP76IZ5.js → chunk-S5PCA3SN.js} +1 -1
  49. package/dist/{chunk-3NSNIIBE.js → chunk-S76AYB4M.js} +17 -16
  50. package/dist/{chunk-RMWLBUCJ.js → chunk-SADUQSO4.js} +1 -1
  51. package/dist/{chunk-OZGHL5Y5.js → chunk-SWCTGCSC.js} +2 -2
  52. package/dist/{chunk-GQD22KKN.js → chunk-T2Q7ISPE.js} +2 -1
  53. package/dist/{chunk-C5Y5ZJJZ.js → chunk-T4Y6SCG3.js} +5 -4
  54. package/dist/{chunk-BWQ66M6N.js → chunk-ULSIJGLS.js} +45 -13
  55. package/dist/{chunk-NNRTPG7X.js → chunk-UYOYTKE2.js} +4 -4
  56. package/dist/{chunk-PTW6W5NR.js → chunk-VYAL7PUE.js} +1 -1
  57. package/dist/{chunk-YZ5F4PIS.js → chunk-W5VPCONO.js} +146 -247
  58. package/dist/{chunk-6Y5RUTHO.js → chunk-WBT5X3NH.js} +5 -4
  59. package/dist/{chunk-RLYZLUQ7.js → chunk-WGAUY5LE.js} +2 -2
  60. package/dist/{chunk-RSNSZ2LJ.js → chunk-X5H2WYMB.js} +1 -1
  61. package/dist/{chunk-OHVJA253.js → chunk-X5N6KC6V.js} +47 -29
  62. package/dist/{chunk-22RMZBGW.js → chunk-XGP3VYOG.js} +1 -1
  63. package/dist/{chunk-HYZRY4KZ.js → chunk-XNGMQ27R.js} +16 -6
  64. package/dist/{chunk-HGECYFEI.js → chunk-Y5GE76XC.js} +131 -54
  65. package/dist/{chunk-MAK5LYRF.js → chunk-Y5MXET4M.js} +277 -535
  66. package/dist/{chunk-XCK2YAY5.js → chunk-YVZJ6GKF.js} +3 -2
  67. package/dist/{chunk-YO4PSLVB.js → chunk-ZRL6HKBY.js} +1 -1
  68. package/dist/claude-launcher-YVXI76NX.js +102 -0
  69. package/dist/{cli-A76AXELQ.js → cli-C77H54BV.js} +468 -161
  70. package/dist/{command-R2QCVX55.js → command-H5CILO4S.js} +40 -37
  71. package/dist/{config-N3C6DFQA.js → config-FXDG4NPJ.js} +2 -3
  72. package/dist/{connect-cmd-JBKAQNSF.js → connect-cmd-ZW5FV3ZW.js} +9 -8
  73. package/dist/{context-adopt-NFHCLVUB.js → context-adopt-O5OFXMKI.js} +13 -12
  74. package/dist/context-materialize-Y5IJ4MQT.js +23 -0
  75. package/dist/{dist-LKDWQWZ7.js → dist-QTX4RSCL.js} +2 -2
  76. package/dist/{docker-4J77Q2BF.js → docker-RC3PRX3Q.js} +7 -8
  77. package/dist/{doctor-4TAIARIG.js → doctor-2NQQML6P.js} +46 -39
  78. package/dist/{emit-artifact-cmd-MPZVR56N.js → emit-artifact-cmd-7MP63KXU.js} +25 -22
  79. package/dist/emit-cmd-PPN4QQF2.js +14 -0
  80. package/dist/{emit-criteria-cmd-EFGYI23V.js → emit-criteria-cmd-3RXPDLNK.js} +16 -14
  81. package/dist/{emit-finding-cmd-5GF3V4LR.js → emit-finding-cmd-OL7JB6H3.js} +18 -16
  82. package/dist/{emit-result-cmd-I4OADKMD.js → emit-result-cmd-UZVMOCF4.js} +20 -17
  83. package/dist/{exec-client-CQV746UF.js → exec-client-7UMESIE2.js} +3 -4
  84. package/dist/governing-source-BUU4IABS.js +35 -0
  85. package/dist/guest-init-KPBQOFE5.js +9 -0
  86. package/dist/{hook-fast-R4FVSZ2H.js → hook-fast-W5MKHMJT.js} +4 -1
  87. package/dist/host-key-U4B5QETR.js +8 -0
  88. package/dist/{import-capture-cmd-EQ35EARA.js → import-capture-cmd-ZO6KGHI2.js} +7 -5
  89. package/dist/{import-ruler-cmd-BGAZXCQM.js → import-ruler-cmd-KJMWL5V6.js} +5 -3
  90. package/dist/index.js +8 -4
  91. package/dist/init-VWXIZEAN.js +54 -0
  92. package/dist/{init-PWU5YVL7.js → init-WNXXYMO7.js} +38 -35
  93. package/dist/{init-cmd-XAVO7HYZ.js → init-cmd-WS6TIRYT.js} +28 -24
  94. package/dist/{init-update-CVCWD6VS.js → init-update-E3J6TVIN.js} +27 -26
  95. package/dist/{install-HDBIPHTX.js → install-CBWIEF3R.js} +4 -5
  96. package/dist/{install-cmd-5HYMXLEW.js → install-cmd-QDOTR4OM.js} +5 -4
  97. package/dist/{login-browser-QZCS3WW6.js → login-browser-O63QZN7D.js} +4 -3
  98. package/dist/{logout-cmd-QAUFDJ6J.js → logout-cmd-5V5MMBSY.js} +3 -2
  99. package/dist/{logs-H55NWW4H.js → logs-AMLKC3VP.js} +3 -1
  100. package/dist/loop-UGI2BJOT.js +76 -0
  101. package/dist/machine-JOW4RNZ7.js +49 -0
  102. package/dist/{mcp-install-cmd-FDTPQQS6.js → mcp-install-cmd-GGWB3JJ2.js} +3 -2
  103. package/dist/{mcp-serve-cmd-3KVYEUXG.js → mcp-serve-cmd-DOTY5FKY.js} +10 -8
  104. package/dist/paths-7XP63OAX.js +7 -0
  105. package/dist/pending-532ABZYC.js +8 -0
  106. package/dist/{pidfile-UZRH774M.js → pidfile-3DM4OBKO.js} +4 -2
  107. package/dist/{record-C43U4PKS.js → record-3WP6V2K5.js} +3 -2
  108. package/dist/{runner-env-EN7YE7QX.js → runner-env-4NB2GA7O.js} +5 -6
  109. package/dist/{runner-key-6SLBI7PP.js → runner-key-TC3NFWFV.js} +38 -35
  110. package/dist/{session-sender-FO3LCREV.js → session-sender-NNVPSPY7.js} +17 -14
  111. package/dist/spec-cmd-OWVTBB4J.js +116 -0
  112. package/dist/{starter-pack-KF66HGZR.js → starter-pack-OPWUDOWX.js} +7 -5
  113. package/dist/{status-7VNQN5PW.js → status-TKCLLKFG.js} +42 -39
  114. package/dist/{statusline-fast-SVTMBMD7.js → statusline-fast-KN3BX67H.js} +2 -1
  115. package/dist/{sync-cmd-GVPPFZ3G.js → sync-cmd-Q6VYNPWG.js} +16 -13
  116. package/dist/{watch-23HSAEI6.js → watch-ARAGADTF.js} +16 -13
  117. package/dist/{work-claim-cmd-LKL3GHFQ.js → work-claim-cmd-34FERLYX.js} +25 -27
  118. package/dist/work-cmd-7S5B2H2P.js +25 -0
  119. package/dist/{work-comment-cmd-AWHP56M2.js → work-comment-cmd-SZJSPM5S.js} +15 -13
  120. package/dist/{work-launch-R5HTAP6X.js → work-launch-LEQ2MPM3.js} +3 -1
  121. package/dist/{work-open-pr-cmd-IOM4AVQQ.js → work-open-pr-cmd-RPXKCBWS.js} +17 -15
  122. package/dist/work-pr-cmd-5LGANL32.js +26 -0
  123. package/package.json +3 -2
  124. package/skill-pack/maintained/outerlayer-amend/SKILL.md +4 -2
  125. package/skill-pack/shipped.json +17 -2
  126. package/skill-pack/template/build/SKILL.md +23 -10
  127. package/skill-pack/template/build/references/agent-briefs.md +3 -1
  128. package/skill-pack/template/build/references/criteria-judge.md +27 -0
  129. package/skill-pack/template/build/references/release.md +19 -28
  130. package/skill-pack/template/spec/SKILL.md +35 -10
  131. package/skill-pack/validators/acceptance-criteria.yaml +25 -26
  132. package/dist/agent-setup-T624CWPD.js +0 -27
  133. package/dist/chunk-BYT5O5RV.js +0 -61
  134. package/dist/context-materialize-IV2TUUFO.js +0 -22
  135. package/dist/emit-cmd-IJ3GVRFD.js +0 -12
  136. package/dist/guest-init-LJP5GPZF.js +0 -9
  137. package/dist/host-key-YMLXY6QB.js +0 -7
  138. package/dist/init-6XPDRDTC.js +0 -51
  139. package/dist/loop-FK3LPMMZ.js +0 -73
  140. package/dist/machine-SQXEBAM2.js +0 -46
  141. package/dist/paths-OYKMVYJP.js +0 -6
  142. package/dist/pending-MXLSRYMO.js +0 -7
  143. package/dist/work-cmd-Z2WXLZPH.js +0 -23
  144. package/dist/work-pr-cmd-HNEUIEN7.js +0 -24
@@ -1,14 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { readPin, pinExists, readBuildHold, readContextManifest, manifestFilesPresent, writeDegraded, writeSourceCache, SOURCE_CACHE_TTL_RETRY_MS, SOURCE_CACHE_TTL_SUCCESS_MS, touchLastCheck, isLastCheckFresh, readDegraded, clearDegraded, writeContextManifest, writePinIfChanged, readSourceCache, isSourceCacheFresh } from './chunk-WTE3MQML.js';
4
- import { removeRetiredSkills } from './chunk-C5Y5ZJJZ.js';
5
- import { appendContextProvenance } from './chunk-ZJSNLVCE.js';
6
- import { defaultFetch } from './chunk-YO4PSLVB.js';
7
- import { withTokenHeader } from './chunk-BYT5O5RV.js';
8
- import { loadMaintainedFiles, writeMaintainedFiles } from './chunk-POJMEEJJ.js';
9
- import { normalizeRepoName, parseGoverns, CONTEXT_SOURCE_CONFIG_PATH, parseOuterlayerConfig, classifyTree, emitTree } from './chunk-OHVJA253.js';
10
- import { resolveGatewayCredentials } from './chunk-PLMTLGYH.js';
3
+ import { readPin, pinExists, readBuildHold, readContextManifest, manifestFilesPresent, writeDegraded, writeSourceCache, SOURCE_CACHE_TTL_RETRY_MS, touchLastCheck, SOURCE_CACHE_TTL_SUCCESS_MS, readDegraded, writeContextManifest, writePinIfChanged, readSourceCache, isSourceCacheFresh, clearDegraded } from './chunk-LXAY4A2G.js';
4
+ import { removeRetiredSkills } from './chunk-T4Y6SCG3.js';
5
+ import { defaultFetch } from './chunk-ZRL6HKBY.js';
6
+ import { resolveGatewayCredentials } from './chunk-52NC2FIU.js';
7
+ import { loadMaintainedFiles, writeMaintainedFiles } from './chunk-MNTSH4CL.js';
8
+ import { normalizeRepoName, parseOuterlayerConfig, classifyTree, emitTree } from './chunk-X5N6KC6V.js';
9
+ import { withTokenHeader } from './chunk-BQXFBI7T.js';
11
10
  import { ensureContextExcludes, ensurePreCommitGuardHook } from './chunk-XCCLFVXM.js';
11
+ import { appendContextProvenance } from './chunk-ZJSNLVCE.js';
12
+ import { cliInvocation } from './chunk-CRB3POP4.js';
12
13
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
13
14
  import { execFileSync } from 'child_process';
14
15
  import { lstatSync, existsSync, mkdirSync, writeFileSync, chmodSync, unlinkSync, readdirSync, rmSync, readFileSync, copyFileSync } from 'fs';
@@ -91,16 +92,20 @@ function gitText(git, cwd, args, timeoutMs) {
91
92
  const result = git(args, { cwd, timeoutMs });
92
93
  return result.ok ? result.stdout.toString("utf8").trim() : void 0;
93
94
  }
95
+ var GATEWAY_TOO_OLD_MESSAGE = "the OuterLayer this machine talks to is too old to name the control plane \u2014 ask whoever runs it to upgrade; context written earlier is kept";
94
96
  var NOT_GOVERNED_MESSAGE = "this repository's control plane no longer governs it";
95
97
  var ADOPTION_MESSAGE = "committed context files shadow the control plane \u2014 remove them in a commit";
96
98
  var CANNOT_IDENTIFY_MESSAGE = "this repository is governed, but the control plane cannot be identified \u2014 check OuterLayer connectivity/config";
97
99
  function designationAuthRejectedMessage(credential) {
98
- return credential.startsWith("olu_") ? "the OuterLayer login was rejected (401/403) \u2014 run `outerlayer login` to sign in again" : "the OuterLayer API key was rejected (401/403) \u2014 check apiKey in ~/.outerlayer/config.json";
100
+ return credential.startsWith("olu_") ? `the OuterLayer login was rejected (401/403) \u2014 run \`${cliInvocation()} login\` to sign in again` : "the OuterLayer API key was rejected (401/403) \u2014 check apiKey in ~/.outerlayer/config.json";
99
101
  }
100
102
  var PARTIAL_WRITE_MESSAGE = "control-plane content could not be fully written \u2014 running on previous context";
101
103
  var OVERLAY_FAILED_MESSAGE = "control-plane content was written but the maintained skills could not be refreshed \u2014 retrying next session";
102
- var COMMIT_GUARD_FOREIGN_NOT_INSTALLED_MESSAGE = "the materialized-context commit guard is NOT installed \u2014 a pre-commit hook this clone did not write occupies that slot \u2014 resolve the conflict or run `outerlayer hooks install-git`";
103
- var COMMIT_GUARD_HOOKSPATH_NOT_INSTALLED_MESSAGE = "the materialized-context commit guard is NOT installed \u2014 hooks are managed via core.hooksPath, which this clone never writes to automatically \u2014 adopt it yourself: `outerlayer hooks install-git --print`";
104
+ function isStagingWriteFault(message) {
105
+ return message === PARTIAL_WRITE_MESSAGE || message === OVERLAY_FAILED_MESSAGE;
106
+ }
107
+ var COMMIT_GUARD_FOREIGN_NOT_INSTALLED_MESSAGE = `the materialized-context commit guard is NOT installed \u2014 a pre-commit hook this clone did not write occupies that slot \u2014 resolve the conflict or run \`${cliInvocation()} hooks install-git\``;
108
+ var COMMIT_GUARD_HOOKSPATH_NOT_INSTALLED_MESSAGE = `the materialized-context commit guard is NOT installed \u2014 hooks are managed via core.hooksPath, which this clone never writes to automatically \u2014 adopt it yourself: \`${cliInvocation()} hooks install-git --print\``;
104
109
  function guardNotInstalledMessage(guard) {
105
110
  if (guard.adopted) return void 0;
106
111
  if (guard.status === "skipped-foreign") return COMMIT_GUARD_FOREIGN_NOT_INSTALLED_MESSAGE;
@@ -188,102 +193,67 @@ async function materializeContext(deps) {
188
193
  if (ownRepoName === void 0) {
189
194
  return selfOutcome();
190
195
  }
191
- const designation = await resolveDesignation({ git, fetchImpl, home, cloud: deps.cloud, now, gitCommonDir, ownRepoName, repoRoot, lookup: deps.designationLookup ?? { timeoutMs: 2e3, attempts: 1 } });
196
+ const designation = deps.pinnedSource === void 0 ? await resolveDesignation({ git, fetchImpl, home, cloud: deps.cloud, now, gitCommonDir, ownRepoName, repoRoot, lookup: deps.designationLookup ?? { timeoutMs: 2e3, attempts: 1 } }) : deps.pinnedSource === null ? { status: "self" } : { status: "governed", ...deps.pinnedSource };
192
197
  const answered = { designation: "answered" };
193
198
  if (designation.status === "self") {
199
+ if (designation.unanswered !== void 0 && !hasPin) {
200
+ const { authRejected, gatewayTooOld } = designation.unanswered;
201
+ const message = authRejected ?? (gatewayTooOld ? GATEWAY_TOO_OLD_MESSAGE : void 0);
202
+ if (message !== void 0) {
203
+ writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "designation-unverified", message });
204
+ }
205
+ return {
206
+ status: "self",
207
+ sha: null,
208
+ verification: "none",
209
+ designation: "unknown",
210
+ ...authRejected ? { authRejected: true } : {},
211
+ ...message !== void 0 && !authRejected ? { message } : {}
212
+ };
213
+ }
194
214
  return { ...selfOutcome(), ...answered };
195
215
  }
196
216
  if (designation.status === "unknown") {
197
- const message = designation.authRejected ?? CANNOT_IDENTIFY_MESSAGE;
217
+ const message = designation.authRejected ?? (designation.gatewayTooOld ? GATEWAY_TOO_OLD_MESSAGE : CANNOT_IDENTIFY_MESSAGE);
198
218
  if (hasPin) {
199
219
  writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "designation-unverified", message });
200
220
  record(null, "none");
201
221
  return { status: "designation-unverified", message, sha: null, verification: "none", designation: "unknown" };
202
222
  }
203
- if (designation.authRejected) {
223
+ if (designation.authRejected || designation.gatewayTooOld) {
204
224
  writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "designation-unverified", message });
205
225
  }
206
- writeSourceCache(gitCommonDir, { checkedAt: new Date(now()).toISOString(), status: "self", ttlMs: SOURCE_CACHE_TTL_RETRY_MS });
207
- return { status: "self", sha: null, verification: "none", designation: "unknown", ...designation.authRejected ? { authRejected: true } : {}, lookupFailure: designation.lookupFailure };
208
- }
209
- let repository;
210
- let ref;
211
- let unverifiedIdentity;
212
- let storedSha;
213
- let preFetched;
214
- let unreadableCandidates = [];
215
- if (designation.status === "candidates") {
216
- const sortedCandidates = [...designation.candidates].sort((a, b) => a.repository.localeCompare(b.repository));
217
- const claimants = [];
218
- const unfetched = [];
219
- const access = await deps.controlPlaneAccess?.(sortedCandidates);
220
- for (const candidate of sortedCandidates) {
221
- const candidateUrl = deps.resolveControlPlaneUrl ? deps.resolveControlPlaneUrl(candidate.repository, candidate.ref, repoRoot) : buildControlPlaneUrl(git, repoRoot, candidate.repository);
222
- const candidateHost = parseRemoteHost(candidateUrl).host || "unknown-host";
223
- const candidateCacheDir = ensureBareCache(git, home, candidate.repository, candidateHost);
224
- const candidateLocalRef = `refs/outerlayer/${sanitizeRefName(candidate.ref)}`;
225
- const token = access !== void 0 && normalizeRepoName(access.repository) === normalizeRepoName(candidate.repository) ? access.token : void 0;
226
- const candidateFetch = git(["fetch", "--depth", "1", candidateUrl, `+${candidate.ref}:${candidateLocalRef}`], {
227
- cwd: candidateCacheDir,
228
- timeoutMs: 1e4,
229
- ...token === void 0 ? {} : { env: (base) => withTokenHeader(base, candidateUrl, token) }
230
- });
231
- if (!candidateFetch.ok) {
232
- unfetched.push(candidate.repository);
233
- continue;
234
- }
235
- const candidateSha = gitText(git, candidateCacheDir, ["rev-parse", candidateLocalRef], 2e3);
236
- if (candidateSha === void 0) {
237
- unfetched.push(candidate.repository);
238
- continue;
239
- }
240
- const candidateConfig = readBlobAtPath(git, candidateCacheDir, candidateSha, CONTEXT_SOURCE_CONFIG_PATH);
241
- const candidateGoverns = candidateConfig === void 0 ? { governs: [] } : parseGoverns(candidateConfig);
242
- const candidateGovernsList = "error" in candidateGoverns ? [] : candidateGoverns.governs;
243
- if (candidateGovernsList.some((r) => normalizeRepoName(r) === normalizeRepoName(ownRepoName))) {
244
- claimants.push({ repository: candidate.repository, ref: candidate.ref, sha: candidateSha, cacheRepoDir: candidateCacheDir });
245
- }
246
- }
247
- if (claimants.length === 0) {
248
- writeSourceCache(gitCommonDir, { checkedAt: new Date(now()).toISOString(), status: "self", ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS });
249
- return { ...selfOutcome(), ...answered, ...unfetched.length > 0 ? { unfetched } : {} };
250
- }
251
- if (claimants.length > 1) {
252
- const names = claimants.map((c) => c.repository).sort();
253
- const message = `${names.join(" and ")} both claim to govern this repository \u2014 resolve the designation before context can materialize`;
254
- writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "conflict", message });
255
- const manifestForConflict = readContextManifest(gitCommonDir);
256
- const lastGood = manifestForConflict?.sha ?? null;
257
- const verification = manifestForConflict ? "unverified" : "none";
258
- record(lastGood, verification);
259
- return { status: "conflict", message, sha: lastGood, verification };
260
- }
261
- unreadableCandidates = unfetched;
262
- const winner = claimants[0];
263
226
  writeSourceCache(gitCommonDir, {
264
227
  checkedAt: new Date(now()).toISOString(),
265
- status: "governed",
266
- repository: winner.repository,
267
- ref: winner.ref,
268
- ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS
228
+ status: "self",
229
+ ttlMs: SOURCE_CACHE_TTL_RETRY_MS,
230
+ unanswered: {
231
+ ...designation.authRejected ? { authRejected: designation.authRejected } : {},
232
+ ...designation.gatewayTooOld ? { gatewayTooOld: true } : {}
233
+ }
269
234
  });
270
- repository = winner.repository;
271
- ref = winner.ref;
272
- preFetched = { sha: winner.sha, cacheRepoDir: winner.cacheRepoDir };
273
- } else {
274
- repository = designation.repository;
275
- ref = designation.ref;
276
- unverifiedIdentity = designation.unverifiedIdentity;
277
- storedSha = designation.sha;
235
+ return {
236
+ status: "self",
237
+ sha: null,
238
+ verification: "none",
239
+ designation: "unknown",
240
+ ...designation.authRejected ? { authRejected: true } : {},
241
+ ...designation.gatewayTooOld ? { message } : {},
242
+ lookupFailure: designation.lookupFailure
243
+ };
278
244
  }
245
+ const repository = designation.repository;
246
+ const ref = designation.ref;
247
+ const unverifiedIdentity = designation.unverifiedIdentity;
248
+ const storedSha = designation.sha;
279
249
  const manifest = readContextManifest(gitCommonDir);
280
- const evidenced = hasGovernedEvidence(hasPin, manifest) || storedSha !== void 0 && !unverifiedIdentity;
250
+ const evidenced = hasGovernedEvidence(hasPin, manifest) || !unverifiedIdentity;
281
251
  const clearOrFlagIdentity = () => {
282
252
  if (unverifiedIdentity) {
283
253
  writeDegraded(gitCommonDir, {
284
254
  at: new Date(now()).toISOString(),
285
255
  kind: "designation-unverified",
286
- message: CANNOT_IDENTIFY_MESSAGE,
256
+ message: designation.gatewayTooOld ? GATEWAY_TOO_OLD_MESSAGE : CANNOT_IDENTIFY_MESSAGE,
287
257
  repository,
288
258
  ref
289
259
  });
@@ -291,132 +261,77 @@ async function materializeContext(deps) {
291
261
  clearDegraded(gitCommonDir);
292
262
  }
293
263
  };
294
- let sha;
295
- let cacheRepoDir;
296
- if (preFetched) {
297
- sha = preFetched.sha;
298
- cacheRepoDir = preFetched.cacheRepoDir;
299
- } else {
300
- if (storedSha !== void 0 && manifest !== void 0 && manifest.sha === storedSha && pin?.sha === storedSha && manifestFilesPresent(repoRoot, manifest)) {
301
- touchLastCheck(gitCommonDir, now());
302
- clearOrFlagIdentity();
303
- ensureContextExcludes(gitCommonDir);
304
- recordMaintainedOverlay(repoRoot, gitCommonDir, manifest);
305
- const guardMessage2 = guardNotInstalledMessage(ensurePreCommitGuardHook(repoRoot, gitCommonDir));
306
- writeSourceCache(gitCommonDir, {
307
- checkedAt: new Date(now()).toISOString(),
308
- status: "governed",
309
- repository,
310
- ref,
311
- sha: storedSha,
312
- ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS
313
- });
314
- const verification = unverifiedIdentity ? "unverified" : "verified";
315
- record(storedSha, verification, repository, ref);
316
- return {
317
- status: "debounced",
318
- sha: storedSha,
319
- verification,
320
- ...guardMessage2 ? { message: guardMessage2 } : {}
321
- };
322
- }
323
- if (storedSha === void 0 && isLastCheckFresh(gitCommonDir, now()) && manifest !== void 0 && pin?.sha === manifest.sha && manifestFilesPresent(repoRoot, manifest)) {
324
- const degraded = readDegraded(gitCommonDir);
325
- const verification = degraded ? "unverified" : "verified";
326
- ensureContextExcludes(gitCommonDir);
327
- recordMaintainedOverlay(repoRoot, gitCommonDir, manifest);
328
- const guardMessage2 = guardNotInstalledMessage(ensurePreCommitGuardHook(repoRoot, gitCommonDir));
329
- record(manifest.sha, verification, repository, ref);
330
- return {
331
- status: "debounced",
332
- sha: manifest.sha,
333
- verification,
334
- ...guardMessage2 ? { message: guardMessage2 } : {}
335
- };
336
- }
337
- const recentFailure = readDegraded(gitCommonDir);
338
- if (recentFailure && (recentFailure.kind === "unreachable" || recentFailure.kind === "no-access") && recentFailure.repository === repository && recentFailure.ref === ref && now() - Date.parse(recentFailure.at) < FAILURE_DEBOUNCE_MS) {
339
- const lastGood = manifest?.sha ?? null;
340
- const verification = lastGood ? "unverified" : "none";
341
- if (evidenced) {
342
- record(lastGood, verification, repository, ref);
343
- return { status: recentFailure.kind, message: recentFailure.message, sha: lastGood, verification };
344
- }
345
- return { status: recentFailure.kind, sha: null, verification: "none" };
346
- }
347
- const remoteUrl = deps.resolveControlPlaneUrl ? deps.resolveControlPlaneUrl(repository, ref, repoRoot) : buildControlPlaneUrl(git, repoRoot, repository);
348
- const cacheHost = parseRemoteHost(remoteUrl).host || "unknown-host";
349
- const lsRemote = storedSha === void 0 ? git(["ls-remote", remoteUrl, ref], { cwd: repoRoot, timeoutMs: 2e3 }) : void 0;
350
- if (lsRemote?.ok) {
351
- const remoteSha = parseLsRemoteSha(lsRemote.stdout.toString("utf8"));
352
- if (remoteSha && manifest !== void 0 && manifest.sha === remoteSha && pin?.sha === remoteSha && manifestFilesPresent(repoRoot, manifest)) {
353
- touchLastCheck(gitCommonDir, now());
354
- clearOrFlagIdentity();
355
- ensureContextExcludes(gitCommonDir);
356
- recordMaintainedOverlay(repoRoot, gitCommonDir, manifest);
357
- const guardMessage2 = guardNotInstalledMessage(ensurePreCommitGuardHook(repoRoot, gitCommonDir));
358
- writeSourceCache(gitCommonDir, { checkedAt: new Date(now()).toISOString(), status: "governed", repository, ref, ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS });
359
- record(remoteSha, "verified", repository, ref);
360
- return {
361
- status: "debounced",
362
- sha: remoteSha,
363
- verification: "verified",
364
- ...guardMessage2 ? { message: guardMessage2 } : {}
365
- };
366
- }
367
- }
368
- cacheRepoDir = ensureBareCache(git, home, repository, cacheHost);
369
- const localRef = storedSha === void 0 ? `refs/outerlayer/${sanitizeRefName(ref)}` : `refs/outerlayer/sha-${sanitizeRefName(storedSha)}`;
370
- const wanted = storedSha === void 0 ? `+${ref}:${localRef}` : `+${storedSha}:${localRef}`;
371
- const access = storedSha === void 0 ? void 0 : await deps.controlPlaneAccess?.([{ repository, ref }]);
372
- const token = access !== void 0 && normalizeRepoName(access.repository) === normalizeRepoName(repository) ? access.token : void 0;
373
- const fetchResult = git(["fetch", "--depth", "1", remoteUrl, wanted], {
374
- cwd: cacheRepoDir,
375
- timeoutMs: 1e4,
376
- ...token === void 0 ? {} : { env: (base) => withTokenHeader(base, remoteUrl, token) }
264
+ if (manifest !== void 0 && manifest.sha === storedSha && pin?.sha === storedSha && manifestFilesPresent(repoRoot, manifest)) {
265
+ touchLastCheck(gitCommonDir, now());
266
+ clearOrFlagIdentity();
267
+ ensureContextExcludes(gitCommonDir);
268
+ recordMaintainedOverlay(repoRoot, gitCommonDir, manifest);
269
+ const guardMessage2 = guardNotInstalledMessage(ensurePreCommitGuardHook(repoRoot, gitCommonDir));
270
+ writeSourceCache(gitCommonDir, {
271
+ checkedAt: new Date(now()).toISOString(),
272
+ status: "governed",
273
+ repository,
274
+ ref,
275
+ sha: storedSha,
276
+ ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS
377
277
  });
378
- const commitNote = (message) => storedSha === void 0 ? message : `could not fetch commit \`${storedSha.slice(0, 7)}\` of ${repository}; ${message}`;
379
- if (!fetchResult.ok) {
380
- const kind = classifyGitFailure(fetchResult.stderr);
381
- const lastGood = manifest?.sha ?? null;
382
- const verification = lastGood ? "unverified" : "none";
383
- const doctorMessage = commitNote(kind === "no-access" ? noAccessMessage(lastGood) : unreachableMessage(lastGood));
384
- writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind, message: doctorMessage, repository, ref, lastGoodSha: lastGood ?? void 0 });
385
- if (evidenced) {
386
- record(lastGood, verification, repository, ref);
387
- return { status: kind, message: doctorMessage, sha: lastGood, verification };
388
- }
389
- return { status: kind, sha: null, verification: "none" };
278
+ const verification = unverifiedIdentity ? "unverified" : "verified";
279
+ record(storedSha, verification, repository, ref);
280
+ return {
281
+ status: "debounced",
282
+ sha: storedSha,
283
+ verification,
284
+ ...guardMessage2 ? { message: guardMessage2 } : {}
285
+ };
286
+ }
287
+ const recentFailure = readDegraded(gitCommonDir);
288
+ if (recentFailure && (recentFailure.kind === "unreachable" || recentFailure.kind === "no-access") && recentFailure.repository === repository && recentFailure.ref === ref && now() - Date.parse(recentFailure.at) < FAILURE_DEBOUNCE_MS) {
289
+ const lastGood = manifest?.sha ?? null;
290
+ const verification = lastGood ? "unverified" : "none";
291
+ if (evidenced) {
292
+ record(lastGood, verification, repository, ref);
293
+ return { status: recentFailure.kind, message: recentFailure.message, sha: lastGood, verification };
390
294
  }
391
- const fetchedSha = gitText(git, cacheRepoDir, ["rev-parse", localRef], 2e3);
392
- if (fetchedSha === void 0 || storedSha !== void 0 && fetchedSha !== storedSha) {
393
- const lastGood = manifest?.sha ?? null;
394
- const verification = lastGood ? "unverified" : "none";
395
- const doctorMessage = commitNote(unreachableMessage(lastGood));
396
- writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "unreachable", message: doctorMessage, repository, ref, lastGoodSha: lastGood ?? void 0 });
397
- if (evidenced) {
398
- record(lastGood, verification, repository, ref);
399
- return { status: "unreachable", message: doctorMessage, sha: lastGood, verification };
400
- }
401
- return { status: "unreachable", sha: null, verification: "none" };
295
+ return { status: recentFailure.kind, sha: null, verification: "none" };
296
+ }
297
+ const remoteUrl = deps.resolveControlPlaneUrl ? deps.resolveControlPlaneUrl(repository, ref, repoRoot) : buildControlPlaneUrl(git, repoRoot, repository);
298
+ const cacheHost = parseRemoteHost(remoteUrl).host || "unknown-host";
299
+ const cacheRepoDir = ensureBareCache(git, home, repository, cacheHost);
300
+ const localRef = `refs/outerlayer/sha-${sanitizeRefName(storedSha)}`;
301
+ const wanted = `+${storedSha}:${localRef}`;
302
+ const access = await deps.controlPlaneAccess?.([{ repository, ref }]);
303
+ const token = access !== void 0 && normalizeRepoName(access.repository) === normalizeRepoName(repository) ? access.token : void 0;
304
+ const fetchResult = git(["fetch", "--depth", "1", remoteUrl, wanted], {
305
+ cwd: cacheRepoDir,
306
+ timeoutMs: 1e4,
307
+ ...token === void 0 ? {} : { env: (base) => withTokenHeader(base, remoteUrl, token) }
308
+ });
309
+ const commitNote = (message) => `could not fetch commit \`${storedSha.slice(0, 7)}\` of ${repository}; ${message}`;
310
+ if (!fetchResult.ok) {
311
+ const kind = classifyGitFailure(fetchResult.stderr);
312
+ const lastGood = manifest?.sha ?? null;
313
+ const verification = lastGood ? "unverified" : "none";
314
+ const doctorMessage = commitNote(kind === "no-access" ? noAccessMessage(lastGood) : unreachableMessage(lastGood));
315
+ writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind, message: doctorMessage, repository, ref, lastGoodSha: lastGood ?? void 0 });
316
+ if (evidenced) {
317
+ record(lastGood, verification, repository, ref);
318
+ return { status: kind, message: doctorMessage, sha: lastGood, verification };
402
319
  }
403
- sha = fetchedSha;
404
- const governed = storedSha !== void 0 || (() => {
405
- const configContent = readBlobAtPath(git, cacheRepoDir, sha, CONTEXT_SOURCE_CONFIG_PATH);
406
- const parsedGoverns = configContent === void 0 ? { governs: [] } : parseGoverns(configContent);
407
- const governsList = "error" in parsedGoverns ? [] : parsedGoverns.governs;
408
- return governsList.some((r) => normalizeRepoName(r) === normalizeRepoName(ownRepoName));
409
- })();
410
- if (!governed) {
411
- writeSourceCache(gitCommonDir, { checkedAt: new Date(now()).toISOString(), status: "self", ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS });
412
- if (hasPin) {
413
- writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "not-governed", message: NOT_GOVERNED_MESSAGE });
414
- return { status: "not-governed", message: NOT_GOVERNED_MESSAGE, sha: pin?.sha ?? null, verification: "none" };
415
- }
416
- clearDegraded(gitCommonDir);
417
- return { status: "self", sha: null, verification: "none" };
320
+ return { status: kind, sha: null, verification: "none" };
321
+ }
322
+ const fetchedSha = gitText(git, cacheRepoDir, ["rev-parse", localRef], 2e3);
323
+ if (fetchedSha !== storedSha) {
324
+ const lastGood = manifest?.sha ?? null;
325
+ const verification = lastGood ? "unverified" : "none";
326
+ const doctorMessage = commitNote(unreachableMessage(lastGood));
327
+ writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "unreachable", message: doctorMessage, repository, ref, lastGoodSha: lastGood ?? void 0 });
328
+ if (evidenced) {
329
+ record(lastGood, verification, repository, ref);
330
+ return { status: "unreachable", message: doctorMessage, sha: lastGood, verification };
418
331
  }
332
+ return { status: "unreachable", sha: null, verification: "none" };
419
333
  }
334
+ const sha = fetchedSha;
420
335
  const tracked = git(["ls-files", "-z", "--", "AGENTS.md", ".claude", ".outerlayer"], { cwd: repoRoot, timeoutMs: 2e3 });
421
336
  if (tracked.ok && tracked.stdout.length > 0) {
422
337
  writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "adoption-conflict", message: ADOPTION_MESSAGE, repository, ref });
@@ -489,7 +404,7 @@ async function materializeContext(deps) {
489
404
  status: "governed",
490
405
  repository,
491
406
  ref,
492
- ...storedSha === void 0 ? {} : { sha: storedSha },
407
+ sha: storedSha,
493
408
  ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS
494
409
  });
495
410
  record(sha, "verified", repository, ref);
@@ -497,8 +412,7 @@ async function materializeContext(deps) {
497
412
  status: "materialized",
498
413
  sha,
499
414
  verification: "verified",
500
- ...guardMessage ? { message: guardMessage } : {},
501
- ...unreadableCandidates.length > 0 ? { unfetched: unreadableCandidates } : {}
415
+ ...guardMessage ? { message: guardMessage } : {}
502
416
  };
503
417
  }
504
418
  function recordMaintainedOverlay(repoRoot, gitCommonDir, manifest) {
@@ -518,11 +432,12 @@ function recordMaintainedOverlay(repoRoot, gitCommonDir, manifest) {
518
432
  }
519
433
  async function resolveDesignation(ctx) {
520
434
  const cache = readSourceCache(ctx.gitCommonDir);
521
- if (cache && isSourceCacheFresh(cache, ctx.now()) && !(cache.status === "governed" && cache.sha !== void 0)) {
522
- return cache.status === "governed" && cache.repository && cache.ref ? { status: "governed", repository: cache.repository, ref: cache.ref } : { status: "self" };
435
+ if (cache && cache.status === "self" && isSourceCacheFresh(cache, ctx.now())) {
436
+ return { status: "self", unanswered: cache.unanswered };
523
437
  }
524
438
  let authRejected;
525
439
  let lookupFailure;
440
+ let gatewayTooOld = false;
526
441
  const destination = resolveGatewayCredentials({
527
442
  home: ctx.home,
528
443
  env: {},
@@ -539,19 +454,7 @@ async function resolveDesignation(ctx) {
539
454
  if (lookup.kind === "rejected") authRejected = designationAuthRejectedMessage(destination.credential);
540
455
  if (lookup.kind === "failed") lookupFailure = lookup.failure;
541
456
  if (lookup.kind === "answered") {
542
- if (lookup.source !== void 0) {
543
- if (lookup.source === null) {
544
- writeSourceCache(ctx.gitCommonDir, {
545
- checkedAt: new Date(ctx.now()).toISOString(),
546
- status: "self",
547
- ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS
548
- });
549
- return { status: "self" };
550
- }
551
- return { status: "governed", repository: lookup.source.repository, ref: lookup.source.ref, sha: lookup.source.sha };
552
- }
553
- const sources = lookup.sources ?? [];
554
- if (sources.length === 0) {
457
+ if (lookup.source === null) {
555
458
  writeSourceCache(ctx.gitCommonDir, {
556
459
  checkedAt: new Date(ctx.now()).toISOString(),
557
460
  status: "self",
@@ -559,19 +462,25 @@ async function resolveDesignation(ctx) {
559
462
  });
560
463
  return { status: "self" };
561
464
  }
562
- return { status: "candidates", candidates: sources };
465
+ if (lookup.source !== void 0) {
466
+ return { status: "governed", repository: lookup.source.repository, ref: lookup.source.ref, sha: lookup.source.sha };
467
+ }
468
+ gatewayTooOld = true;
563
469
  }
564
470
  }
565
- if (cache) {
566
- return cache.status === "governed" && cache.repository && cache.ref ? {
567
- status: "governed",
568
- repository: cache.repository,
569
- ref: cache.ref,
570
- unverifiedIdentity: true,
571
- ...cache.sha === void 0 ? {} : { sha: cache.sha }
471
+ if (cache?.status === "self") {
472
+ return cache.unanswered !== void 0 || authRejected !== void 0 || gatewayTooOld ? {
473
+ status: "self",
474
+ unanswered: { ...cache.unanswered, ...authRejected ? { authRejected } : {}, ...gatewayTooOld ? { gatewayTooOld } : {} }
572
475
  } : { status: "self" };
573
476
  }
574
- return { status: "unknown", authRejected, lookupFailure };
477
+ if (cache?.repository && cache.ref && cache.sha !== void 0) {
478
+ return { status: "governed", repository: cache.repository, ref: cache.ref, sha: cache.sha, unverifiedIdentity: true, ...gatewayTooOld ? { gatewayTooOld } : {} };
479
+ }
480
+ return { status: "unknown", authRejected, gatewayTooOld, lookupFailure };
481
+ }
482
+ async function lookupGoverningSource(config, repository, fetchImpl, lookup) {
483
+ return fetchContextSource(config, repository, fetchImpl, lookup);
575
484
  }
576
485
  async function fetchContextSource(config, ownRepoName, fetchImpl, lookup) {
577
486
  const url = `${config.url.replace(/\/$/, "")}/v1/context/source?repo=${encodeURIComponent(ownRepoName)}`;
@@ -602,10 +511,10 @@ async function askContextSource(url, config, fetchImpl, timeoutMs) {
602
511
  const body = await res.json();
603
512
  const data = body.data;
604
513
  const source = validSource(data?.source);
605
- if (data === void 0 || data === null || source === void 0 && !Array.isArray(data.sources)) {
606
- return { kind: "failed", failure: { kind: "network", message: "the answer named no sources" } };
514
+ if (typeof data !== "object" || data === null) {
515
+ return { kind: "failed", failure: { kind: "network", message: "the answer held no data" } };
607
516
  }
608
- return { kind: "answered", source, sources: data.sources };
517
+ return { kind: "answered", source };
609
518
  } catch (err) {
610
519
  return {
611
520
  kind: "failed",
@@ -676,12 +585,6 @@ function ensureBareCache(git, home, repository, host) {
676
585
  }
677
586
  return dir;
678
587
  }
679
- function parseLsRemoteSha(output) {
680
- const lines = output.split("\n").filter((l) => l.trim().length > 0);
681
- const peeled = lines.find((l) => l.split(/\s+/)[1]?.endsWith("^{}"));
682
- const line = peeled ?? lines[0];
683
- return line?.split(/\s+/)[0];
684
- }
685
588
  var MATERIALIZED_ROOTS = ["AGENTS.md", ".claude", ".outerlayer"];
686
589
  function listMaterializedFiles(git, cacheRepoDir, sha) {
687
590
  const result = git(["ls-tree", "-r", "-z", sha, "--", ...MATERIALIZED_ROOTS], { cwd: cacheRepoDir, timeoutMs: 1e4 });
@@ -702,10 +605,6 @@ function listMaterializedFiles(git, cacheRepoDir, sha) {
702
605
  }
703
606
  return entries;
704
607
  }
705
- function readBlobAtPath(git, cacheRepoDir, sha, path) {
706
- const result = git(["show", `${sha}:${path}`], { cwd: cacheRepoDir, timeoutMs: 5e3 });
707
- return result.ok ? result.stdout.toString("utf8") : void 0;
708
- }
709
608
  function parseBatchReply(files, stdout) {
710
609
  const parsed = [];
711
610
  let pos = 0;
@@ -794,4 +693,4 @@ function pruneEmptyDirs(dir, stopAt) {
794
693
  }
795
694
  }
796
695
 
797
- export { defaultGitRunner, hasSymlinkComponent, materializeContext, parseOwnerRepo, parseRemoteHost, resolveGitCommonDir };
696
+ export { defaultGitRunner, hasSymlinkComponent, isStagingWriteFault, lookupGoverningSource, materializeContext, parseOwnerRepo, parseRemoteHost, resolveGitCommonDir };
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { fetchFactories, selectFactory, saveFactoryConnection, autoConnectedLine } from './chunk-3NSNIIBE.js';
4
- import { resolveRepoIdentity } from './chunk-JXYVA45C.js';
5
- import { resolveGatewayCredentials } from './chunk-PLMTLGYH.js';
3
+ import { fetchFactories, selectFactory, saveFactoryConnection, autoConnectedLine } from './chunk-S76AYB4M.js';
4
+ import { resolveRepoIdentity } from './chunk-BMYGAGBJ.js';
5
+ import { resolveGatewayCredentials } from './chunk-52NC2FIU.js';
6
6
  import { findGitDirs, readRepoConnection } from './chunk-BJ3KTMDH.js';
7
+ import { cliInvocation } from './chunk-CRB3POP4.js';
7
8
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
8
9
 
9
10
  createRequire(import.meta.url);
@@ -22,7 +23,7 @@ async function autoConnect(opts) {
22
23
  if (!listed.ok || listed.factories.length === 0) return void 0;
23
24
  const chosen = selectFactory(listed.factories, readRepoConnection(cwd), repository);
24
25
  if (chosen.factory === void 0) {
25
- return `you are logged in, but no factory is chosen for this repository, and more than one fits. Run \`outerlayer connect --factory <org>/<factory>\` with one of:
26
+ return `you are logged in, but no factory is chosen for this repository, and more than one fits. Run \`${cliInvocation()} connect --factory <org>/<factory>\` with one of:
26
27
  ${chosen.text}
27
28
  Or pass --app-id / set OUTERLAYER_APP_ID.`;
28
29
  }
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { builtinKind } from './chunk-22RMZBGW.js';
3
+ import { builtinKind } from './chunk-XGP3VYOG.js';
4
4
  import { parseSize } from './chunk-7RQ73DLO.js';
5
- import { runnerDir } from './chunk-ZM2IMMYN.js';
5
+ import { runnerDir } from './chunk-N2PXGQRL.js';
6
6
  import { dirname } from 'path';
7
7
  import { spawnSync } from 'child_process';
8
8
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { RELAY_PORT, GATEWAY_SOCKET, GATEWAY_PORT, CLAUDE_SOCKET, CLAUDE_PORT, DESTINATION_BASE_PORT } from './chunk-4Q7OMKAT.js';
3
+ import { RELAY_PORT, GATEWAY_SOCKET, GATEWAY_PORT, CLAUDE_SOCKET, CLAUDE_PORT, DESTINATION_BASE_PORT } from './chunk-BQXFBI7T.js';
4
4
  import { symlinkSync, unlinkSync } from 'fs';
5
5
  import { join } from 'path';
6
6