@bongos/core 1.19.715 → 1.19.724

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 (414) hide show
  1. package/.bongos-core.json +472 -407
  2. package/.claude/skills/backlog-review/SKILL.md +3 -3
  3. package/.claude/skills/blocker-review/SKILL.md +1 -1
  4. package/.claude/skills/blocker-solve/SKILL.md +2 -2
  5. package/.claude/skills/builder-reauth/SKILL.md +1 -1
  6. package/.claude/skills/builder-redteam/SKILL.md +1 -1
  7. package/.claude/skills/builder-ship/SKILL.md +1 -1
  8. package/.claude/skills/builder-start/SKILL.md +1 -1
  9. package/.claude/skills/design/SKILL.md +2 -2
  10. package/.claude/skills/feedback/SKILL.md +1 -1
  11. package/.claude/skills/goal-create/SKILL.md +1 -1
  12. package/.claude/skills/goal-review/SKILL.md +2 -2
  13. package/.claude/skills/idea-triage/SKILL.md +5 -5
  14. package/.claude/skills/merge-mode/SKILL.md +4 -4
  15. package/.claude/skills/new-project/SKILL.md +17 -17
  16. package/.claude/skills/planning-session/SKILL.md +11 -11
  17. package/.claude/skills/recall/SKILL.md +2 -2
  18. package/.claude/skills/strand-fix/SKILL.md +1 -1
  19. package/.devcontainer/README.md +2 -2
  20. package/CONTRIBUTING.md +2 -2
  21. package/GOVERNANCE.md +4 -4
  22. package/clients/bongos-client/README.md +1 -1
  23. package/clients/bongos-client/bongos-client.global.js +4 -0
  24. package/clients/bongos-client/index.cjs +4 -0
  25. package/clients/bongos-client/index.d.ts +5 -0
  26. package/clients/bongos-client/index.mjs +4 -0
  27. package/config/branding.neutral.json +4 -2
  28. package/docs/adr/0001-stack-choice-single-vps.md +2 -2
  29. package/docs/adr/0002-digitalocean-over-hetzner.md +1 -1
  30. package/docs/adr/0008-google-chat-oauth-user-auth.md +1 -1
  31. package/docs/adr/0009-autotile-architecture.md +1 -1
  32. package/docs/adr/0011-terrain-id-rendering-model.md +3 -3
  33. package/docs/adr/0013-paths-as-object-overlays-with-autotile-dispatch.md +1 -1
  34. package/docs/adr/0014-families-canonical-over-vocabulary.md +1 -1
  35. package/docs/adr/0015-task-dependencies-and-auto-promotion.md +1 -1
  36. package/docs/adr/0016-trust-boundary-server-enforced-permissions.md +1 -1
  37. package/docs/adr/0018-three-rank-model-goes-live.md +3 -3
  38. package/docs/adr/0020-security-model-public-stub.md +9 -9
  39. package/docs/adr/0021-per-builder-skill-model-preferences.md +2 -2
  40. package/docs/adr/0022-secrets-policy.md +5 -5
  41. package/docs/adr/0024-cloneable-repo-local-first-memory.md +3 -3
  42. package/docs/adr/0024-multi-agent-system-architecture.md +10 -10
  43. package/docs/adr/0025-offsite-backup-vendor-digitalocean-spaces.md +1 -1
  44. package/docs/adr/0025-structured-criterion-task-link.md +1 -1
  45. package/docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md +13 -13
  46. package/docs/adr/0027-bfg-session-inefficiency-evaluator.md +14 -14
  47. package/docs/adr/0029-status-page-outage-resilience.md +1 -1
  48. package/docs/adr/0030-builders-hall-live-updates.md +1 -1
  49. package/docs/adr/0031-cloud-dev-environments-for-builders.md +7 -7
  50. package/docs/adr/0032-discord-mirror-of-gds.md +3 -3
  51. package/docs/adr/0033-discord-bot-service-principal.md +4 -4
  52. package/docs/adr/0034-thetes-graduated-newcomer-rank.md +1 -1
  53. package/docs/adr/0035-builder-onboarding-three-paths.md +4 -4
  54. package/docs/adr/0036-builders-subdomain-and-ui-reorg.md +1 -1
  55. package/docs/adr/0037-discord-channel-management.md +1 -1
  56. package/docs/adr/0038-chromebook-ttyd-cloudflare-tunnel.md +5 -5
  57. package/docs/adr/0039-setup-first-onboarding-ux.md +6 -6
  58. package/docs/adr/0040-remote-control-default-browser-onramp.md +3 -3
  59. package/docs/adr/0041-temporary-grader-bypass-killswitch.md +2 -2
  60. package/docs/adr/0042-builder-self-deploy-ci-auto-merge.md +5 -5
  61. package/docs/adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md +2 -2
  62. package/docs/adr/0044-mediterranean-palette-replacement.md +1 -1
  63. package/docs/adr/0044-per-box-live-game-preview.md +1 -1
  64. package/docs/adr/0046-sandbox-first-review-gate.md +1 -1
  65. package/docs/adr/0047-discord-bugs-intake-anti-abuse.md +1 -1
  66. package/docs/adr/0049-split-parallel-safety-contract.md +1 -1
  67. package/docs/adr/0050-device-flow-admission-invite-gated-by-default.md +2 -2
  68. package/docs/adr/0051-full-session-transcript-corpus.md +2 -2
  69. package/docs/adr/0052-sandbox-for-everyone-game-only-preview.md +1 -1
  70. package/docs/adr/0053-scoped-dev-box-session.md +1 -1
  71. package/docs/adr/0054-session-token-reward-cost-plus.md +7 -7
  72. package/docs/adr/0055-server-mediated-branch-publish.md +2 -2
  73. package/docs/adr/0056-prod-deploy-script-mirror-and-healthcheck-retry.md +3 -3
  74. package/docs/adr/0057-container-cost-ledger.md +1 -1
  75. package/docs/adr/0057-discord-archon-approval-channels.md +2 -2
  76. package/docs/adr/0058-automatic-gate-surface-gatekeeper.md +6 -6
  77. package/docs/adr/0059-single-approval-remove-devbox-approval-gate.md +11 -11
  78. package/docs/adr/0060-gds-retrieval-layer.md +3 -3
  79. package/docs/adr/0061-context-layer-decomposition.md +2 -2
  80. package/docs/adr/0062-medusa-instance-model-decoupling.md +5 -5
  81. package/docs/adr/0063-generated-repo-map-symbol-skeleton.md +2 -2
  82. package/docs/adr/0064-rename-medusa-to-cloud-bongos.md +3 -3
  83. package/docs/adr/0065-agpl-nonprofit-ai-first-governance.md +5 -5
  84. package/docs/adr/0066-generated-file-map-sections.md +2 -2
  85. package/docs/adr/0067-session-start-fast-forward-pull.md +1 -1
  86. package/docs/adr/0068-shared-art-key-for-newcomers.md +1 -1
  87. package/docs/adr/0069-hall-live-channel-sse-decouple.md +3 -3
  88. package/docs/adr/0070-deterministic-session-card-delivery.md +1 -1
  89. package/docs/adr/0071-box-confirm-before-destroyed-and-drift-reconcile.md +2 -2
  90. package/docs/adr/0072-bongos-app-mac-signed-first-windows-deferred.md +2 -2
  91. package/docs/adr/0072-dev-box-code-staleness-visibility.md +2 -2
  92. package/docs/adr/0073-builder-needs-signal-and-byok-gemini-key.md +3 -3
  93. package/docs/adr/0073-secrets-scan-exclude-uri-detector.md +2 -2
  94. package/docs/adr/0076-in-session-deterministic-compaction.md +2 -2
  95. package/docs/adr/0077-content-addressed-llm-cache.md +2 -2
  96. package/docs/adr/0078-deterministic-first-cron.md +3 -3
  97. package/docs/adr/0079-value-gated-autonomous-engagement.md +2 -2
  98. package/docs/adr/0080-llm-cache-api-transport-and-trust-model.md +3 -3
  99. package/docs/adr/0081-tool-agnostic-design-layer.md +3 -3
  100. package/docs/adr/0082-server-side-merge-conflict-auto-resolution.md +2 -2
  101. package/docs/adr/0083-modular-architecture-strangler-build-plan.md +3 -3
  102. package/docs/adr/0085-remove-default-per-builder-spend-cap.md +2 -2
  103. package/docs/adr/0086-goal-scoped-work-hierarchy.md +15 -15
  104. package/docs/adr/0087-bongos-app-architecture-and-handoff-contract.md +5 -5
  105. package/docs/adr/0087-compete-on-governance-not-tooling-cursor.md +1 -1
  106. package/docs/adr/0088-consistent-character-generative-animation.md +5 -5
  107. package/docs/adr/0089-modular-multi-model-adversarial-grader.md +15 -15
  108. package/docs/adr/0090-metic-task-authoring.md +8 -8
  109. package/docs/adr/0091-bounding-the-kernel-and-db-carve.md +3 -3
  110. package/docs/adr/0092-hosting-module-and-on-prem-target.md +11 -11
  111. package/docs/adr/0093-tranche-2-core-carve-sequence.md +5 -5
  112. package/docs/adr/0094-repo-atlas-self-drawing-codebase-map.md +1 -1
  113. package/docs/adr/0095-borrowed-memory-and-retrieval-concepts.md +6 -6
  114. package/docs/adr/0095-cross-agent-context-management.md +5 -5
  115. package/docs/adr/0096-require-reward-before-workable.md +5 -5
  116. package/docs/adr/0097-one-active-claim-per-session-and-worktree-binding.md +2 -2
  117. package/docs/adr/0097-retroactive-reward-backfill.md +4 -4
  118. package/docs/adr/0098-public-mirror-publish-manifest.md +3 -3
  119. package/docs/adr/0099-delayed-redacted-mirror-export.md +1 -1
  120. package/docs/adr/0100-two-repo-instance-model.md +6 -6
  121. package/docs/adr/0101-goal-hierarchy-phase-5-judge-membership-reward.md +9 -9
  122. package/docs/adr/0102-finish-bounding-the-kernel.md +1 -1
  123. package/docs/adr/0103-core-first-extraction-cloud-bongos-trunk.md +6 -6
  124. package/docs/adr/0103-gdsv4-bongos-consolidation.md +3 -3
  125. package/docs/adr/0104-trust-gds-api-channel-in-auto-mode.md +3 -3
  126. package/docs/adr/0105-instance-seed-migrations-out-of-core.md +2 -2
  127. package/docs/adr/0106-goal-owner-manager-authority.md +2 -2
  128. package/docs/adr/0107-module-upstreaming-contribution-to-core-catalog.md +6 -6
  129. package/docs/adr/0108-instance-composition-configurable-root.md +6 -6
  130. package/docs/adr/0109-self-describing-openapi-and-hosted-docs.md +3 -3
  131. package/docs/adr/0110-untrack-whole-file-generated-nav-docs.md +1 -1
  132. package/docs/adr/0111-instance-hosting-provisioning-module.md +18 -18
  133. package/docs/adr/0112-private-goals-invitations-join-requests.md +7 -7
  134. package/docs/adr/0113-sandbox-studio-descope-superseded-by-0044-0052.md +1 -1
  135. package/docs/adr/0114-instance-docs-discovery-contract.md +4 -4
  136. package/docs/adr/0115-scheduled-routines-portability.md +1 -1
  137. package/docs/adr/0117-api-versioning-and-deprecation-policy.md +1 -1
  138. package/docs/adr/0118-api-contract-source-of-truth-code-first.md +1 -1
  139. package/docs/adr/0120-pay-on-land-and-builder-owned-rebase-gate.md +2 -2
  140. package/docs/adr/0121-greenfield-vs-brownfield-onboarding-adopt-existing-repo.md +1 -1
  141. package/docs/adr/0122-onboarding-diagram-renders-deploy-rendered-off-git.md +3 -3
  142. package/docs/adr/0123-box-idle-sweep-autosave-before-destroy.md +1 -1
  143. package/docs/adr/0124-typed-api-response-bodies.md +2 -2
  144. package/docs/adr/0125-control-plane-scaffolds-standalone-instance-repo.md +2 -2
  145. package/docs/adr/0126-dedicated-cloudbongos-control-plane-droplet.md +3 -3
  146. package/docs/adr/0127-cross-box-fleet-observability.md +1 -1
  147. package/docs/adr/0128-provisioning-runner-privilege-and-db-auth-model.md +3 -3
  148. package/docs/adr/0129-cloudbongos-control-plane-pull-deploy.md +4 -4
  149. package/docs/adr/0130-provision-remote-exec-over-ssh.md +4 -4
  150. package/docs/adr/0131-rank-scoped-skill-visibility.md +2 -2
  151. package/docs/adr/0132-cohost-fleet-control-plane-migration.md +2 -2
  152. package/docs/adr/0133-github-app-manifest-onboarding-signin.md +1 -1
  153. package/docs/adr/0134-private-first-npm-distribution.md +3 -3
  154. package/docs/adr/0135-module-upstream-submission-interim-queue.md +1 -1
  155. package/docs/adr/0136-update-channel-subscription-policy.md +2 -2
  156. package/docs/adr/0137-upstream-publish-policy-manual-owner-gated.md +6 -6
  157. package/docs/adr/0138-bundled-module-deps-declared-per-module.md +4 -4
  158. package/docs/adr/0142-project-context-is-prose-only.md +2 -2
  159. package/docs/adr/0143-onboarding-repo-picker-oauth-scope.md +2 -2
  160. package/docs/adr/0144-devbox-rehome-onto-cloudbongos-plane.md +2 -2
  161. package/docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md +2 -2
  162. package/docs/adr/0146-configurable-reward-mode-cost-plus-only.md +4 -4
  163. package/docs/adr/0147-standalone-live-docs-regen.md +1 -1
  164. package/docs/adr/0149-bongos-dev-local-launcher.md +1 -1
  165. package/docs/adr/0150-box-first-boot-bringup-vendored-instances.md +3 -3
  166. package/docs/adr/0151-governance-permissions-as-atom-ranks-as-roles.md +20 -20
  167. package/docs/adr/0152-landing-gate-served-by-the-core-app.md +2 -2
  168. package/docs/adr/0152-metic-task-abandonment.md +7 -7
  169. package/docs/adr/0153-sequential-chain-runner.md +1 -1
  170. package/docs/adr/0154-goal-owner-criterion-authoring.md +7 -7
  171. package/docs/adr/0155-adopt-private-repo-widen-oauth-scope.md +2 -2
  172. package/docs/adr/0156-user-set-display-name-wins.md +1 -1
  173. package/docs/adr/0157-archon-is-rank-and-identity-only.md +10 -10
  174. package/docs/adr/0158-choke-point-verdict-taxonomy.md +1 -1
  175. package/docs/adr/0159-merge-gate-reconciliation.md +1 -1
  176. package/docs/adr/0160-main-audit-repo-verifiable-caller.md +1 -1
  177. package/docs/adr/0161-publish-on-merge.md +2 -2
  178. package/docs/adr/0163-legacy-display-name-resolution.md +1 -1
  179. package/docs/adr/0165-instances-hookless-by-default.md +1 -1
  180. package/docs/adr/0166-module-maintenance-and-deprecation-policy.md +3 -3
  181. package/docs/adr/0167-gate-trust-link-agpl-default.md +2 -2
  182. package/docs/adr/0167-module-catalog-source-vs-provenance.md +3 -3
  183. package/docs/adr/0169-bongos-serve-server-bring-up.md +1 -1
  184. package/docs/adr/0171-profile-rollup-join-and-consent.md +1 -1
  185. package/docs/adr/0172-editable-rank-roles-substrate-axis.md +2 -2
  186. package/docs/adr/0172-per-craft-compensation-ideator-credit-lane.md +4 -4
  187. package/docs/adr/0173-legacy-multi-ship-shortfall-not-backfilled.md +1 -1
  188. package/docs/adr/0174-government-terminology-ranks-not-roles.md +1 -1
  189. package/docs/adr/0177-goal-membership-kind.md +3 -3
  190. package/docs/adr/0178-the-copy-desk-flag-and-queue.md +1 -1
  191. package/docs/adr/0179-board-membership-predicate-grammar.md +1 -1
  192. package/docs/adr/0181-teardown-state-gate-and-address-retention.md +1 -1
  193. package/docs/adr/0182-project-visibility-two-axes.md +1 -1
  194. package/docs/adr/0183-criteria-close-themselves.md +1 -1
  195. package/docs/adr/0184-ship-requires-an-assurance.md +1 -1
  196. package/docs/adr/0185-spark-handoff-credit-split.md +1 -1
  197. package/docs/adr/0186-per-project-idea-templates.md +1 -1
  198. package/docs/adr/0187-collab-four-decisions.md +1 -1
  199. package/docs/adr/0187-oauth-handshake-cookie-lifetime.md +1 -1
  200. package/docs/adr/0188-patrol-runs-on-ci-not-the-server.md +2 -2
  201. package/docs/adr/0189-baseline-floors-and-the-freeze-detector.md +2 -2
  202. package/docs/adr/0191-majority-and-the-author-who-may-not-decide-alone.md +1 -1
  203. package/docs/adr/0192-a-category-orients-and-authorises-nothing.md +2 -2
  204. package/docs/adr/0193-pause-task-scoped-box-slices.md +1 -1
  205. package/docs/adr/0195-adr-numbers-are-checked-like-migration-numbers.md +2 -2
  206. package/docs/adr/0196-chrome-world-token-contract-and-the-landing-sheets.md +2 -2
  207. package/docs/adr/0197-the-ui-design-module.md +1 -1
  208. package/docs/adr/0198-third-party-skill-vendoring-policy.md +1 -1
  209. package/docs/adr/0203-doorway-changelog-out-of-module-api.md +2 -2
  210. package/docs/adr/0204-the-apex-is-dark-only.md +2 -2
  211. package/docs/adr/0205-federated-checkin-needs-the-hubs-own-signin-witness.md +1 -1
  212. package/docs/adr/0206-own-scoped-session-revocation-no-absolute-ceiling.md +1 -1
  213. package/docs/adr/0207-connections-implementation-departures-and-honest-limits.md +1 -1
  214. package/docs/adr/0208-application-lifecycle-the-handle-waits-and-the-vouch-has-no-minter.md +2 -2
  215. package/docs/adr/0209-one-budget-for-the-account-existence-oracle.md +1 -1
  216. package/docs/adr/0210-scouting-graduates-on-an-instance-asserted-owner-claim.md +1 -1
  217. package/docs/adr/0212-connections-on-the-profile-surface-and-addressing.md +1 -1
  218. package/docs/adr/0213-platform-terms-acceptance-is-the-hubs-own-witness.md +2 -2
  219. package/docs/adr/0215-the-recruiter-sliver-is-a-ceiling-not-a-step.md +6 -6
  220. package/docs/adr/0216-a-fake-pool-interpreter-must-fail-loudly-not-silently-ignore.md +2 -2
  221. package/docs/adr/0217-rank-gates-inviting-not-viewing.md +1 -1
  222. package/docs/adr/0218-the-apex-root-web-surface.md +2 -2
  223. package/docs/adr/0219-a-look-is-a-branding-pack-the-style-library.md +1 -1
  224. package/docs/adr/0220-an-in-house-rebuilt-skill-is-a-first-party-skill.md +1 -1
  225. package/docs/adr/0221-the-impeccable-method-is-one-skill-with-sub-command-playbooks.md +2 -2
  226. package/docs/adr/0222-the-image-family-under-the-hero-only-rule.md +2 -2
  227. package/docs/adr/0223-the-detector-is-two-tiers-in-the-kit.md +3 -3
  228. package/docs/adr/0224-module-skills-reach-the-core-checkout-as-untracked-self-ignored-copies.md +1 -1
  229. package/docs/adr/0225-privacy-suppresses-cross-project-surfaces-only.md +1 -1
  230. package/docs/adr/0226-one-stale-timer-reporting-degrades-enforcement-refuses.md +1 -1
  231. package/docs/adr/0227-a-task-network-map-is-refused-the-goal-graph-is-the-map.md +1 -1
  232. package/docs/adr/0230-a-look-skill-is-a-composition-grammar-the-palette-is-the-pack.md +1 -1
  233. package/docs/adr/0231-the-style-session-an-owner-authors-a-look-inside-the-contract.md +2 -2
  234. package/docs/adr/0232-rot-is-derived-not-swept-and-water-is-the-only-new-verb.md +2 -2
  235. package/docs/adr/0233-a-copy-proposal-is-a-task-carrying-a-patch.md +2 -2
  236. package/docs/adr/0234-idea-routing-capture-time-promotion-landing-matrix-homeless-inbox.md +2 -2
  237. package/docs/adr/0235-a-fix-category-is-kindbug-under-a-goal-no-column-required.md +11 -11
  238. package/docs/adr/0236-many-ideas-one-task-the-lineage-key-is-the-pair.md +5 -5
  239. package/docs/adr/0237-a-starter-bundle-is-a-preset-over-the-always-on-core-keyed-by-declared-type.md +5 -5
  240. package/docs/adr/0238-the-join-door-is-a-provisioning-settings-policy-key.md +1 -1
  241. package/docs/adr/0239-a-recommendation-is-a-table-that-carries-its-own-reason.md +4 -4
  242. package/docs/adr/0240-a-skipped-module-picker-stores-nothing-and-resolves-the-bundle-on-read.md +4 -4
  243. package/docs/adr/0241-the-artist-gate-is-a-per-project-deploy-gate-that-reads-a-state.md +1 -1
  244. package/docs/adr/0242-a-cascade-is-a-declaration-table-on-the-event-that-already-exists.md +2 -2
  245. package/docs/adr/0243-a-bundle-adjustment-belongs-to-the-bundle-not-the-advice-about-it.md +4 -4
  246. package/docs/adr/0244-a-catalog-search-is-a-view-over-the-rows-never-an-edit-to-the-selection.md +3 -3
  247. package/docs/adr/0245-the-way-back-into-an-optional-step-is-that-step-s-own-answer-route.md +7 -7
  248. package/docs/adr/0246-catalog-membership-is-a-projection-not-a-federation-side-effect.md +1 -1
  249. package/docs/adr/0247-the-join-door-is-one-composed-answer-and-dark-matter-has-no-live-verdict-yet.md +2 -2
  250. package/docs/adr/0248-a-hub-project-s-owner-is-the-provisioning-row-carried-on-a-port.md +3 -3
  251. package/docs/adr/0249-the-invite-step-is-the-done-panel-s-first-act-not-a-rail-step.md +3 -3
  252. package/docs/adr/0250-strict-versioning-the-version-boundary-is-the-scope-gate.md +6 -6
  253. package/docs/adr/0251-a-suggestion-of-who-to-invite-is-a-recruiting-surface-and-owes-the-opt-out.md +5 -5
  254. package/docs/adr/0252-the-self-hosted-visibility-report-is-a-pull-and-auto-appear-buys-a-retraction-lever.md +19 -19
  255. package/docs/adr/0253-the-takedown-lever-has-two-writers-and-provenance-is-a-column.md +2 -2
  256. package/docs/adr/0254-a-relayed-link-is-contained-downward-or-it-is-not-published.md +6 -6
  257. package/docs/adr/0255-a-public-lists-ordering-is-part-of-its-payload.md +2 -2
  258. package/docs/adr/0256-the-visibility-ceiling-is-the-sign-in-gate-too-and-the-reader-moves-to-the-composer.md +3 -3
  259. package/docs/adr/0257-auth-resolves-before-the-hall-mounts-anything.md +1 -1
  260. package/docs/adr/0258-the-public-cli-is-a-generated-client-package-not-the-published-core.md +1 -1
  261. package/docs/adr/0259-a-projects-departure-from-the-public-list-is-public.md +7 -7
  262. package/docs/adr/0260-the-application-is-the-consent-and-the-echo-is-the-gate.md +4 -4
  263. package/docs/adr/0261-a-preselect-always-carries-a-reason-the-bundle-summary-is-the-floor.md +1 -1
  264. package/docs/adr/0262-a-bug-never-lands-in-the-inbox.md +1 -1
  265. package/docs/adr/0263-how-a-version-closes.md +3 -3
  266. package/docs/adr/0264-the-ten-working-areas.md +3 -3
  267. package/docs/adr/0265-work-with-no-goal-and-the-order-the-cut-needs.md +5 -5
  268. package/docs/adr/0266-the-board-room-is-its-own-surface-reachable-by-whoever-may-vote.md +2 -2
  269. package/docs/adr/0267-unanimity-and-the-revise-and-re-sit-loop.md +1 -1
  270. package/docs/adr/0268-the-constitution-comes-from-two-roots.md +3 -3
  271. package/docs/adr/0269-the-cli-session-store-is-host-keyed-at-a-fixed-anchor.md +1 -1
  272. package/docs/adr/0270-rank-floor-derives-without-a-prediction.md +2 -2
  273. package/docs/adr/0271-the-ideator-surface-is-two-halves.md +3 -3
  274. package/docs/adr/0272-a-craft-is-an-identity-not-a-toolchain.md +4 -4
  275. package/docs/adr/0273-hall-nav-can-gate-on-a-permission.md +1 -1
  276. package/docs/adr/0274-one-kernel-three-role-packs.md +1 -1
  277. package/docs/adr/0275-one-source-for-a-written-role-responsibility.md +1 -1
  278. package/docs/adr/0276-the-skill-listing-budget-cannot-hold-every-trigger.md +1 -1
  279. package/docs/adr/0277-a-box-is-in-use-only-while-a-human-is-attached.md +1 -1
  280. package/docs/adr/0278-a-gated-project-still-takes-applications.md +2 -2
  281. package/docs/adr/0279-an-upgrade-is-proven-by-the-served-version-not-the-health-check.md +1 -1
  282. package/docs/adr/0280-the-unattended-lane-may-drive-a-co-tenant-because-the-roster-is-the-decision.md +1 -1
  283. package/docs/adr/0281-an-instance-identity-is-its-own-unix-account-and-pg-role.md +2 -2
  284. package/docs/adr/README.md +294 -294
  285. package/docs/api/openapi.json +72 -5
  286. package/docs/api-reference.md +8 -2
  287. package/docs/architecture.md +22 -22
  288. package/docs/branding-contract.md +5 -5
  289. package/docs/canonical-permissions.md +22 -22
  290. package/docs/design/hall-direction-v2.md +3 -3
  291. package/docs/design/landing-page-direction-v2.md +1 -1
  292. package/docs/design/projects-hub-direction-v2.md +1 -1
  293. package/docs/file-map.md +3 -1
  294. package/docs/module-api-changelog.md +34 -1
  295. package/docs/modules-contract.md +25 -25
  296. package/docs/onboarding/browser-terminal-guide.md +1 -1
  297. package/docs/onboarding/diagrams/README.md +3 -3
  298. package/docs/onboarding/drachmae-and-karma.md +13 -13
  299. package/docs/onboarding/primer.md +7 -7
  300. package/docs/packs/artist.md +1 -1
  301. package/docs/packs/ideator.md +1 -1
  302. package/docs/project-context.template.md +3 -3
  303. package/docs/recipes/builder-box-lifecycle.md +5 -5
  304. package/docs/recipes/claude-design-loop.md +1 -1
  305. package/docs/recipes/core-release-pipeline.md +55 -14
  306. package/docs/recipes/figma-design-loop.md +1 -1
  307. package/docs/recipes/gds-db-backup.md +2 -2
  308. package/docs/recipes/instance-deploy.md +2 -2
  309. package/docs/recipes/instance-service-restart.md +3 -3
  310. package/docs/recipes/local-dev.md +2 -2
  311. package/docs/recipes/managed-settings-remote-control.md +3 -3
  312. package/docs/recipes/memory-backup.md +4 -4
  313. package/docs/recipes/memory-sync-conflicts.md +2 -2
  314. package/docs/recipes/multi-builder-merge.md +2 -2
  315. package/docs/recipes/ops-gotchas.md +4 -4
  316. package/docs/recipes/overnight-builder.md +1 -1
  317. package/docs/recipes/packaging-the-core.md +6 -6
  318. package/docs/recipes/private-npm-distribution.md +5 -5
  319. package/docs/recipes/search-index-ingestion.md +3 -3
  320. package/docs/recipes/self-host.md +5 -5
  321. package/docs/recipes/server-bring-up.md +1 -1
  322. package/docs/recipes/ship-and-regrade.md +2 -2
  323. package/docs/recipes/standalone-live-docs.md +1 -1
  324. package/docs/recipes/ui-look-before-you-ship.md +1 -1
  325. package/docs/recipes/upgrading-the-core.md +2 -2
  326. package/docs/recipes/work-on-a-task-from-your-dev-box.md +6 -6
  327. package/docs/research/cursor-competitive-analysis.md +3 -3
  328. package/docs/research/llm-model-agnostic-and-cheaper-grader.md +7 -7
  329. package/migrations/core_240_artist_gate_indexes.sql +48 -0
  330. package/migrations/core_240_goal_members_drop_legacy_role.sql +79 -0
  331. package/modules/dev-box/app/src/vendor/bongos-client.cjs +4 -0
  332. package/modules/lifecycle/cascade.js +37 -9
  333. package/modules/lifecycle/db-claims.js +5 -2
  334. package/modules/lifecycle/db-goals.js +4 -3
  335. package/modules/lifecycle/db-overrides.js +117 -4
  336. package/modules/lifecycle/db-tasks.js +63 -0
  337. package/modules/lifecycle/migrations/lifecycle_001_goal_first_leads.sql +12 -4
  338. package/modules/lifecycle/module.json +2 -1
  339. package/modules/lifecycle/pg-constraint-fail.js +49 -0
  340. package/modules/lifecycle/routes/artist-gate.js +101 -0
  341. package/modules/lifecycle/routes/claims.js +13 -1
  342. package/modules/lifecycle/routes/lifecycle.js +6 -0
  343. package/modules/lifecycle/routes/task-write-routes.js +7 -0
  344. package/modules/lifecycle/routes/tasks.js +24 -0
  345. package/modules/lifecycle/task-classifier.js +10 -1
  346. package/modules/lifecycle/tests/cascade.mjs +43 -0
  347. package/modules/provisioning/provisioning.js +79 -3
  348. package/modules/provisioning/routes/provisioning.js +6 -1
  349. package/modules/provisioning/tests/provisioning.mjs +8 -8
  350. package/modules/security/secret-scrub.js +40 -4
  351. package/modules/status-ui/public/README.md +1 -1
  352. package/modules/ui-design/docs/design-contract.md +2 -2
  353. package/modules/ui-design/kit/README.md +1 -1
  354. package/modules/ui-design/kit/serve.js +1 -0
  355. package/modules/ui-design/skills/README.md +6 -6
  356. package/modules/ui-design/skills/brandkit/SKILL.md +1 -1
  357. package/modules/ui-design/skills/design-taste-frontend/SKILL.md +1 -1
  358. package/modules/ui-design/skills/design-taste-frontend-v1/SKILL.md +1 -1
  359. package/modules/ui-design/skills/gpt-taste/SKILL.md +1 -1
  360. package/modules/ui-design/skills/high-end-visual-design/SKILL.md +1 -1
  361. package/modules/ui-design/skills/image-to-code/SKILL.md +1 -1
  362. package/modules/ui-design/skills/imagegen-frontend-mobile/SKILL.md +1 -1
  363. package/modules/ui-design/skills/imagegen-frontend-web/SKILL.md +1 -1
  364. package/modules/ui-design/skills/impeccable/SKILL.md +1 -1
  365. package/modules/ui-design/skills/industrial-brutalist-ui/SKILL.md +1 -1
  366. package/modules/ui-design/skills/minimalist-ui/SKILL.md +1 -1
  367. package/modules/ui-design/skills/redesign-existing-projects/SKILL.md +1 -1
  368. package/modules/ui-design/skills/stitch-design-taste/SKILL.md +1 -1
  369. package/modules/ui-design/skills/style/SKILL.md +2 -2
  370. package/modules/ui-design/styles/README.md +3 -3
  371. package/modules/ui-design/styles/blueprint/DESIGN.md +1 -1
  372. package/modules/ui-design/styles/chrome-world/DESIGN.md +1 -1
  373. package/package-lock.json +2 -2
  374. package/package.json +1 -1
  375. package/scripts/gds/audit-rank-roles.js +172 -0
  376. package/scripts/gds/build-cli-package.js +1 -0
  377. package/scripts/gds/claim.js +94 -9
  378. package/scripts/gds/fitness.js +8 -8
  379. package/scripts/gds/go-live.js +139 -5
  380. package/scripts/gds/land-watch.js +13 -5
  381. package/scripts/gds/mirror-redact.js +13 -2
  382. package/scripts/gds/package-core.js +11 -3
  383. package/scripts/gds/release.js +55 -0
  384. package/scripts/gds/ship-land.js +10 -2
  385. package/scripts/gds/ship-regen.js +41 -8
  386. package/scripts/gds/start.js +7 -4
  387. package/scripts/gds/worktree-claim-guard.js +27 -1
  388. package/scripts/public-mirror-export.js +17 -4
  389. package/src/bongos/api-errors.js +9 -0
  390. package/src/bongos/artist-gate.js +204 -0
  391. package/src/branding.js +15 -0
  392. package/src/module-api.js +34 -1
  393. package/tests/api_path_404.mjs +28 -0
  394. package/tests/artist_gate.mjs +234 -0
  395. package/tests/artist_gate_release.mjs +283 -0
  396. package/tests/artist_gate_route.mjs +174 -0
  397. package/tests/box_scope_predicate.mjs +117 -0
  398. package/tests/claim_error_surface.mjs +163 -1
  399. package/tests/cli_exit_no_abort.mjs +256 -3
  400. package/tests/currency_label.mjs +11 -4
  401. package/tests/go_live.mjs +144 -0
  402. package/tests/main_worktree_busy_reason.mjs +167 -0
  403. package/tests/membership_kind_lockstep.mjs +88 -0
  404. package/tests/mirror_redact.mjs +14 -0
  405. package/tests/module_api.mjs +6 -0
  406. package/tests/provision_settings_apply.mjs +13 -5
  407. package/tests/provisioning_settings.mjs +11 -7
  408. package/tests/provisioning_settings_apply.mjs +4 -4
  409. package/tests/provisioning_settings_env.mjs +59 -7
  410. package/tests/public_mirror_export.mjs +12 -0
  411. package/tests/rank_roles_audit.mjs +114 -0
  412. package/tests/scrubber_corpus.mjs +70 -2
  413. package/tests/start_rebase_warning.mjs +50 -0
  414. package/tests/task_field_bounds_match_db.mjs +140 -0
@@ -1,6 +1,6 @@
1
1
  # Recipe — per-builder dev box lifecycle (provision · auto-suspend · reclaim)
2
2
 
3
- > **Task [#598](https://example.com/builders#/task/598) · [ADR 0031](../adr/<redacted>.md) §2/§5/§9.3.** This is the operator guide for the per-builder DigitalOcean dev boxes. The code ships in the repo; **going live is a deliberate, money-spending operator action** (like `provision-staging.sh`) — nothing here runs until you set `DO_API_TOKEN` and pass `--apply`.
3
+ > **Task [#598](https://example.com/builders#/task/598) · [ADR 0031](../adr/0031-cloud-dev-environments-for-builders.md) §2/§5/§9.3.** This is the operator guide for the per-builder DigitalOcean dev boxes. The code ships in the repo; **going live is a deliberate, money-spending operator action** (like `provision-staging.sh`) — nothing here runs until you set `DO_API_TOKEN` and pass `--apply`.
4
4
 
5
5
  ## The shape
6
6
 
@@ -59,7 +59,7 @@ node scripts/gds/box.js reconcile-drift # DO⇄DB drift; add --apply to
59
59
 
60
60
  `<builder>` is a GitHub login or a numeric builder id.
61
61
 
62
- ### Drift reconcile — `reconcile-drift` (task [#1289](https://example.com/builders#/task/1289), [ADR 0071](../adr/<redacted>.md))
62
+ ### Drift reconcile — `reconcile-drift` (task [#1289](https://example.com/builders#/task/1289), [ADR 0071](../adr/0071-box-confirm-before-destroyed-and-drift-reconcile.md))
63
63
 
64
64
  The teardown is now **confirm-before-destroyed**: `deprovision` only marks a box `destroyed` AFTER DigitalOcean confirms the droplet is deleted (idempotent + retried). A delete that genuinely fails parks the box at `state='error'` with `droplet_id` preserved and **throws** — it never silently leaves a running droplet behind a `destroyed` row (the old "zombie" bug).
65
65
 
@@ -135,8 +135,8 @@ These spend money and are intentionally manual.
135
135
  ```
136
136
  Tail `journalctl -u box-idle-suspend.service` for a day to confirm boxes park + wake cleanly.
137
137
  > **`box-intent-runner.timer` ([#701](https://example.com/builders#/task/701)) is the on-ramp's responsiveness knob.** It runs `box.js run-intents --apply` every minute, draining the `box_intents` queue that `POST /api/gds/box/ensure` writes — so a builder who hits "connect" gets their box **auto-provisioned** (no box yet) or **woken** (parked) within ~1 min, with no operator CLI. It reads the SAME `/etc/example/box.env` as the sweeps. Without it installed, `ensure` still queues intents — they just sit pending until someone runs `box.js run-intents --apply` by hand. Confirm with `journalctl -u box-intent-runner.service` after a test `ensure`.
138
- > **`box-drift-reconcile.timer` (task [#1289](https://example.com/builders#/task/1289)/[ADR 0071](../adr/<redacted>.md)) is the zombie backstop.** It runs `box.js reconcile-drift --apply` hourly, reading the live DO droplet list and repairing DO⇄DB drift both ways — force-deleting **zombie** droplets (running but no live box row claims them) and marking **ghost** rows destroyed (droplet gone from DO). Reads the SAME `/etc/example/box.env` (needs `DO_API_TOKEN` to enumerate droplets). Without it, the confirm-before-destroyed teardown still prevents *new* zombies, but a pre-existing one (or an out-of-band DO change) only heals on the next manual `reconcile-drift`. Confirm with `journalctl -u box-drift-reconcile.service`.
139
- > **Chromebook / browser terminal ([#760](https://example.com/builders#/task/760)/[ADR 0038](../adr/<redacted>.md), superseding the old `claude rc` pairing).** Research proved `claude rc` cannot run headless, so the box instead serves its OWN browser terminal — **ttyd** (127.0.0.1:7681, per-box basic-auth, drops into `/workspace`) exposed over an outbound-only **Cloudflare Tunnel** — where the builder runs normal interactive `claude`. A browser/Chromebook builder gets the URL + credential from `GET /api/gds/box/terminal` after their box is active — no SSH needed. The terminal/cloudflared units are inlined in cloud-init and start at first boot ([#774](https://example.com/builders#/task/774)). The deleted RC bits (`claude-rc.service`, `box-report-pairing.sh`, `/box/pairing(-link)`) are gone.
138
+ > **`box-drift-reconcile.timer` (task [#1289](https://example.com/builders#/task/1289)/[ADR 0071](../adr/0071-box-confirm-before-destroyed-and-drift-reconcile.md)) is the zombie backstop.** It runs `box.js reconcile-drift --apply` hourly, reading the live DO droplet list and repairing DO⇄DB drift both ways — force-deleting **zombie** droplets (running but no live box row claims them) and marking **ghost** rows destroyed (droplet gone from DO). Reads the SAME `/etc/example/box.env` (needs `DO_API_TOKEN` to enumerate droplets). Without it, the confirm-before-destroyed teardown still prevents *new* zombies, but a pre-existing one (or an out-of-band DO change) only heals on the next manual `reconcile-drift`. Confirm with `journalctl -u box-drift-reconcile.service`.
139
+ > **Chromebook / browser terminal ([#760](https://example.com/builders#/task/760)/[ADR 0038](../adr/0038-chromebook-ttyd-cloudflare-tunnel.md), superseding the old `claude rc` pairing).** Research proved `claude rc` cannot run headless, so the box instead serves its OWN browser terminal — **ttyd** (127.0.0.1:7681, per-box basic-auth, drops into `/workspace`) exposed over an outbound-only **Cloudflare Tunnel** — where the builder runs normal interactive `claude`. A browser/Chromebook builder gets the URL + credential from `GET /api/gds/box/terminal` after their box is active — no SSH needed. The terminal/cloudflared units are inlined in cloud-init and start at first boot ([#774](https://example.com/builders#/task/774)). The deleted RC bits (`claude-rc.service`, `box-report-pairing.sh`, `/box/pairing(-link)`) are gone.
140
140
 
141
141
  ## Cloudflare token: the edge cookie-strip rule (ADR 0053 / SR#11)
142
142
 
@@ -164,7 +164,7 @@ curl -sI https://term-<login>.<apex>/ -H 'Cookie: x=1' # from a box-facing che
164
164
  ## Boundaries (other ADR-0031 tasks)
165
165
 
166
166
  - **[#596](https://example.com/builders#/task/596)** (done) — the devcontainer (box-as-code) this provisions.
167
- - **[#599](https://example.com/builders#/task/599)** — Claude Desktop managed-settings + the stable-hostname cutover the lifecycle records. (The browser-on-ramp is now the ttyd web terminal over a Cloudflare Tunnel — [#760](https://example.com/builders#/task/760)/[ADR 0038](../adr/<redacted>.md) — not the retired `claude rc` Remote-Control service.)
167
+ - **[#599](https://example.com/builders#/task/599)** — Claude Desktop managed-settings + the stable-hostname cutover the lifecycle records. (The browser-on-ramp is now the ttyd web terminal over a Cloudflare Tunnel — [#760](https://example.com/builders#/task/760)/[ADR 0038](../adr/0038-chromebook-ttyd-cloudflare-tunnel.md) — not the retired `claude rc` Remote-Control service.)
168
168
  - **[#600](https://example.com/builders#/task/600)** — rank-gated **source access**: the scoped GitHub credential the box holds, granted/revoked by rank. [#598](https://example.com/builders#/task/598) records `scope`; [#600](https://example.com/builders#/task/600) enforces it.
169
169
  - **[#602](https://example.com/builders#/task/602)** — cost passthrough (org-funded starter → self-fund via the `costs`/example system). [#598](https://example.com/builders#/task/598) logs the cost; [#602](https://example.com/builders#/task/602) rebills it.
170
170
 
@@ -1,7 +1,7 @@
1
1
  # Recipe: Claude Design loop
2
2
 
3
3
  > End-to-end guide for the repo ↔ Claude Design sync cycle.
4
- > ADR: [ADR 0081](../adr/<redacted>.md).
4
+ > ADR: [ADR 0081](../adr/0081-tool-agnostic-design-layer.md).
5
5
  > Adapter: `modules/ui-design/adapters/claude-design/index.js` (the `ui-design` module — ADR 0197).
6
6
  > CLI: `modules/ui-design/scripts/design-sync.js` (`scripts/gds/design-sync.js` is a thin shim over it).
7
7
  > Skill: `.claude/skills/design-sync/SKILL.md`.
@@ -4,7 +4,7 @@
4
4
  >
5
5
  > ## **Merging to `main` ships nothing.**
6
6
  >
7
- > A change that has landed on `main` is running on **zero** instances. It reaches users only after someone bumps `CORE_VERSION`, cuts an artifact, and moves an instance's pin. Those are three separate acts by design ([ADR 0137](../adr/<redacted>.md)) — and every layer around them reports success in the meantime.
7
+ > A change that has landed on `main` is running on **zero** instances. It reaches users only after someone bumps `CORE_VERSION`, cuts an artifact, and moves an instance's pin. Those are three separate acts by design ([ADR 0137](../adr/0137-upstream-publish-policy-manual-owner-gated.md)) — and every layer around them reports success in the meantime.
8
8
 
9
9
  ## Why this file exists
10
10
 
@@ -33,7 +33,7 @@ Bongos vocabulary collides with gate 1 in a way worth naming: **task status `shi
33
33
 
34
34
  ## Gate 0 — does your change ship at all?
35
35
 
36
- The core is not "this repo." It is exactly the subtree [`isPublishable()`](../../scripts/gds/publish-manifest.js) selects ([ADR 0098](../adr/<redacted>.md)) — a **default-deny, two-layer** gate:
36
+ The core is not "this repo." It is exactly the subtree [`isPublishable()`](../../scripts/gds/publish-manifest.js) selects ([ADR 0098](../adr/0098-public-mirror-publish-manifest.md)) — a **default-deny, two-layer** gate:
37
37
 
38
38
  ```
39
39
  isPublishable(p) == matchesDeny(p) ? false : matchesAllow(p)
@@ -50,7 +50,7 @@ A path publishes only if it falls in `PUBLISH_ALLOWLIST` **and** escapes `PUBLIS
50
50
  | **Content / copyright** — the instance's product layer and all art | `modules/game/`, `modules/art-pipeline/`, `public/`, `brand/` |
51
51
  | **Host-module tests** — tests that statically import an excluded module | see the list in `publish-manifest.js` |
52
52
 
53
- Note the deliberate non-exclusion: the rank / trust-boundary / ship-grade machinery **is published** — it is the open-source methodology ([ADR 0065 §4](../adr/<redacted>.md)). Only the *topology* subset of the protected surfaces is held back.
53
+ Note the deliberate non-exclusion: the rank / trust-boundary / ship-grade machinery **is published** — it is the open-source methodology ([ADR 0065 §4](../adr/0065-agpl-nonprofit-ai-first-governance.md)). Only the *topology* subset of the protected surfaces is held back.
54
54
 
55
55
  Check a path before you assume:
56
56
 
@@ -60,7 +60,7 @@ node -e "console.log(require('./scripts/gds/publish-manifest').isPublishable('do
60
60
 
61
61
  ## Gate 1 — land it on `main`
62
62
 
63
- The ordinary claim→ship loop: `/builder-claim N` → build → `/builder-ship`. That chains `completed` → `confirmed` → `shipped`, and credits land at `shipped` ([ADR 0120](../adr/<redacted>.md)).
63
+ The ordinary claim→ship loop: `/builder-claim N` → build → `/builder-ship`. That chains `completed` → `confirmed` → `shipped`, and credits land at `shipped` ([ADR 0120](../adr/0120-pay-on-land-and-builder-owned-rebase-gate.md)).
64
64
 
65
65
  Landing is CI-gated (tasks 1002610/1002611/1002619, ADR 0159): every PR runs the **`unit`** check — the DB-free suite plus the fitness gates, via `npm test` — and branch protection **requires** it, so a red suite blocks the merge. PRs touching the hard-floor safety surfaces ([`CODEOWNERS`](../../CODEOWNERS)) additionally need the owner's review. The owner kill-switch is `node scripts/gds/gating.js on|off|status` — reversible by construction, snapshot-restored.
66
66
 
@@ -72,9 +72,9 @@ Three steps. The first two are ordinary claimed work; only the publish (2c) is o
72
72
 
73
73
  ### 2a. Bump `CORE_VERSION` — the step with no automation behind it
74
74
 
75
- `CORE_VERSION` lives in [`src/module-api.js`](../../src/module-api.js) and is bumped **by hand, inside a claimed task**, with an entry appended to the release ledger [`docs/module-api-changelog.md`](../module-api-changelog.md) in the same commit. (The ledger used to be a comment block inside `module-api.js`; appending to it there on every CI release grew the file past the oversized-file fitness ratchet and broke `unit` on `main` — [ADR 0203](../adr/<redacted>.md).) The version's provenance stays in git history + ledger ([ADR 0137](../adr/<redacted>.md) §2).
75
+ `CORE_VERSION` lives in [`src/module-api.js`](../../src/module-api.js) and is bumped **by hand, inside a claimed task**, with an entry appended to the release ledger [`docs/module-api-changelog.md`](../module-api-changelog.md) in the same commit. (The ledger used to be a comment block inside `module-api.js`; appending to it there on every CI release grew the file past the oversized-file fitness ratchet and broke `unit` on `main` — [ADR 0203](../adr/0203-doorway-changelog-out-of-module-api.md).) The version's provenance stays in git history + ledger ([ADR 0137](../adr/0137-upstream-publish-policy-manual-owner-gated.md) §2).
76
76
 
77
- Semver here is not decoration — it decides **who receives the change automatically** ([ADR 0136](../adr/<redacted>.md)):
77
+ Semver here is not decoration — it decides **who receives the change automatically** ([ADR 0136](../adr/0136-update-channel-subscription-policy.md)):
78
78
 
79
79
  | Bump | Reaches `patch` subscribers (the default) | Reaches `minor` subscribers |
80
80
  |---|---|---|
@@ -99,7 +99,7 @@ node scripts/gds/package-core.js --ref main --self-verify
99
99
 
100
100
  ### 2c. Publish — automatic on merge
101
101
 
102
- **Every merge to `main` publishes** ([ADR 0161](../adr/<redacted>.md), superseding ADR 0137's manual gate): once the required `unit` check succeeds on a main push, the `publish` workflow auto-bumps a **patch** if nobody bumped (via `scripts/gds/bump-version.js`, which writes the literal AND appends the ledger entry to [`docs/module-api-changelog.md`](../module-api-changelog.md) — ADR 0203; the carrier commit stages both), builds through the fail-closed no-leak gate with `--self-verify`, publishes, and tags `core-v<version>`. A **minor/major is still a human in-task bump** — CI never makes that call, because it decides what patch-channel subscribers receive unattended.
102
+ **Every merge to `main` publishes** ([ADR 0161](../adr/0161-publish-on-merge.md), superseding ADR 0137's manual gate): once the required `unit` check succeeds on a main push, the `publish` workflow auto-bumps a **patch** if nobody bumped (via `scripts/gds/bump-version.js`, which writes the literal AND appends the ledger entry to [`docs/module-api-changelog.md`](../module-api-changelog.md) — ADR 0203; the carrier commit stages both), builds through the fail-closed no-leak gate with `--self-verify`, publishes, and tags `core-v<version>`. A **minor/major is still a human in-task bump** — CI never makes that call, because it decides what patch-channel subscribers receive unattended.
103
103
 
104
104
  The lane is armed by the owner via the `PUBLISH_ON_MERGE=1` repo variable + two secrets (`NPM_TOKEN`, `RELEASE_PUSH_TOKEN`); while disarmed it no-ops loudly. Manual fallback, same command CI runs:
105
105
 
@@ -152,8 +152,8 @@ carries the target, and names every halt condition it found. Add `--apply` to mo
152
152
 
153
153
  It **halts rather than guessing** on exactly the things that need judgement — unreleased commits
154
154
  on `main`, a registry missing the target, a dirty tree on either end, a failed health check, an
155
- uncommitted pin. When it halts, fall through to the manual steps below and use your own head;
156
- that is what the rest of this section is for.
155
+ uncommitted pin, and an unresolved artist review (see below). When it halts, fall through to the
156
+ manual steps below and use your own head; that is what the rest of this section is for.
157
157
 
158
158
  Two flags worth knowing:
159
159
 
@@ -164,6 +164,47 @@ Two flags worth knowing:
164
164
  - `--allow-unreleased` downgrades the UNRELEASED halt to a warning. Reach for it only when you
165
165
  have already confirmed *why* main is ahead of its last release.
166
166
 
167
+ **The one halt that is not about git: `ARTIST_REVIEW_UNRESOLVED`** (task 1003575,
168
+ [ADR 0241](../adr/0241-the-artist-gate-is-a-per-project-deploy-gate-that-reads-a-state.md)).
169
+ A project running `artist_gate: 'strict'` — the default — may not move its pin while a
170
+ cascade-filed **artist review task** is still open. Note what it is and is not: it reads a task
171
+ *status*, never an artist's opinion, and it holds **this gate only**. Nothing about a builder's
172
+ ship, grade, merge, credit or landing on `main` consults it, which is exactly what lets a gate
173
+ that stops work coexist with [ADR 0162](../adr/0162-review-gates-retired-rank-consistent-ci-only.md).
174
+
175
+ There are three ways past it, and the first two are the ordinary ones:
176
+
177
+ 1. **Resolve or dismiss the reviews.** Shipping one, or abandoning it in triage, is what the
178
+ gate reads — the same board moves as any other task.
179
+ 2. **Lower the setting.** `PATCH /provisioning/instances/:id/settings` with
180
+ `artist_gate: 'advisory'` keeps the reviews being filed and stops them holding deploys.
181
+ (Raising it back to `strict` is **not retroactive** — reviews filed before the raise never
182
+ hold again.)
183
+ 3. **Release one.** `POST /tasks/:id/override-request` with a rationale, then the **project
184
+ owner** approves it at `POST /override-requests/:id/decide`. Three things about that, each of
185
+ which is a deliberate narrowing rather than a new mechanism:
186
+
187
+ - It is the *same* request flow as the grader bypass — ADR 0241 §3 rules out a second
188
+ authority path — but the **owner alone** may decide this class. An Archon is refused with
189
+ `override_owner_only`, and that is correct, not a bug.
190
+ - Approving it **confirms nothing and pays nothing.** The review stays open on the board;
191
+ what stops is its hold on the pin. (A release is why `POST /tasks/:id/override-request`
192
+ accepts an artist review at `backlog` at all — the completed-only rule still applies to
193
+ every other task.)
194
+ - A **self-release** (owner is also the builder or the artist) is permitted and written to
195
+ the audit log as a self-override. It is the valve that stops a solo project deadlocking,
196
+ not a routine step: the right answer to being gated is to fix the work or fix the grader.
197
+
198
+ `go-live.js` prints the gate's level on every plan, held or not, so "why did nothing stop?" is
199
+ answerable without going and looking. Two different unknowns, two different verdicts:
200
+
201
+ - It cannot *reach* the gate (no CLI session, or an instance too old to serve `/api/bongos/artist-gate`) —
202
+ a **note**, not a halt. We do not know the gate applies, and bricking the pin over that would
203
+ leave no task id to release against.
204
+ - The route is there and **errors** — `ARTIST_GATE_UNREADABLE`, a **halt**. The gate applies and
205
+ will not answer, and a broken read must never be a quieter way past it than the owner's own
206
+ override. The fix is in the instance's logs, not on anyone's review queue.
207
+
167
208
  Host topology (ssh alias, box paths, service names, health URL) lives in a host-owned
168
209
  `config/go-live.json`, never in the core — run `node scripts/gds/go-live.js --help` for the
169
210
  schema. A core that named one instance's box would not be a core.
@@ -268,10 +309,10 @@ Exit codes: `0` aligned, `1` diverged, `2` undetermined.
268
309
  | Land a change on `main` | 1 | any builder holding a claim, behind the required `unit` check (protected paths are Metic+; hard-floor paths need owner review per [`CODEOWNERS`](../../CODEOWNERS); [canonical-permissions](../canonical-permissions.md)) |
269
310
  | Bump `CORE_VERSION` | 2a | a builder, inside a claimed task |
270
311
  | Build the artifact | 2b | any builder — `package-core` is tokenless and network-free |
271
- | Publish to npm | 2c | **automatic on merge** once the owner arms the lane ([ADR 0161](../adr/<redacted>.md)); the manual `--publish --live` fallback stays owner-only |
312
+ | Publish to npm | 2c | **automatic on merge** once the owner arms the lane ([ADR 0161](../adr/0161-publish-on-merge.md)); the manual `--publish --live` fallback stays owner-only |
272
313
  | Move an instance's pin | 3 | whoever operates that instance |
273
314
 
274
- Automating gate 2c (a tag-triggered CI publish) is deliberately deferred until a real fleet makes the manual step a bottleneck — see [ADR 0137](../adr/<redacted>.md) "When to revisit".
315
+ Automating gate 2c (a tag-triggered CI publish) is deliberately deferred until a real fleet makes the manual step a bottleneck — see [ADR 0137](../adr/0137-upstream-publish-policy-manual-owner-gated.md) "When to revisit".
275
316
 
276
317
  ## Where to go next
277
318
 
@@ -280,6 +321,6 @@ Automating gate 2c (a tag-triggered CI publish) is deliberately deferred until a
280
321
  | build / verify / inspect the artifact | [packaging-the-core](packaging-the-core.md) |
281
322
  | publish it, or set up private npm access | [private-npm-distribution](private-npm-distribution.md) |
282
323
  | move an instance from N → N+1, or subscribe it to updates | [upgrading-the-core](upgrading-the-core.md) |
283
- | know *why* publishing is manual | [ADR 0137](../adr/<redacted>.md) |
284
- | know *what* an unattended upgrade is allowed to take | [ADR 0136](../adr/<redacted>.md) |
285
- | know what counts as "the core" | [ADR 0098](../adr/<redacted>.md) · [ADR 0103](../adr/<redacted>.md) |
324
+ | know *why* publishing is manual | [ADR 0137](../adr/0137-upstream-publish-policy-manual-owner-gated.md) |
325
+ | know *what* an unattended upgrade is allowed to take | [ADR 0136](../adr/0136-update-channel-subscription-policy.md) |
326
+ | know what counts as "the core" | [ADR 0098](../adr/0098-public-mirror-publish-manifest.md) · [ADR 0103](../adr/0103-core-first-extraction-cloud-bongos-trunk.md) |
@@ -1,7 +1,7 @@
1
1
  # Recipe: Figma round-trip loop
2
2
 
3
3
  > End-to-end guide for the repo ↔ Figma sync cycle — the human escape hatch in ADR 0081.
4
- > ADR: [ADR 0081](../adr/<redacted>.md).
4
+ > ADR: [ADR 0081](../adr/0081-tool-agnostic-design-layer.md).
5
5
  > Adapter: `modules/ui-design/adapters/figma/index.js` (the `ui-design` module — ADR 0197).
6
6
  > CLI: `modules/ui-design/scripts/figma-design-sync.js` (`scripts/gds/figma-design-sync.js` is a thin shim over it).
7
7
  > Skill: `.claude/skills/figma-design-sync/SKILL.md`.
@@ -1,6 +1,6 @@
1
1
  # Recipe — Bongos DB backup (local nightly + offsite weekly)
2
2
 
3
- > **Filed by:** task [#412](https://example.com/builders#/task/412) (V3.R62-precondition, local nightly) + [#415](https://example.com/builders#/task/415) (V3.R62-offsite, weekly offsite archive) — both under [ADR 0024](../adr/<redacted>.md) §5 (backup cadence). Vendor choice for the offsite copy: [ADR 0025](../adr/<redacted>.md) (DigitalOcean Spaces).
3
+ > **Filed by:** task [#412](https://example.com/builders#/task/412) (V3.R62-precondition, local nightly) + [#415](https://example.com/builders#/task/415) (V3.R62-offsite, weekly offsite archive) — both under [ADR 0024](../adr/0024-cloneable-repo-local-first-memory.md) §5 (backup cadence). Vendor choice for the offsite copy: [ADR 0025](../adr/0025-offsite-backup-vendor-digitalocean-spaces.md) (DigitalOcean Spaces).
4
4
  > **Two layers:** a **local daily** `pg_dump` to `/var/backups/gds/` (protects against corruption / bad migration / accidental delete) **plus** a **weekly offsite copy** of the latest local dump to a DigitalOcean Space (protects against whole-droplet loss).
5
5
  > **Reads:** `/etc/systemd/system/gds-db-backup.{service,timer}` (copies of [`scripts/gds/gds-db-backup.service`](../../scripts/gds/gds-db-backup.service) / [`.timer`](../../scripts/gds/gds-db-backup.timer)) + [`scripts/gds/db-backup-nightly.sh`](../../scripts/gds/db-backup-nightly.sh); `/etc/systemd/system/gds-db-offsite.{service,timer}` (copies of [`scripts/gds/gds-db-offsite.service`](../../scripts/gds/gds-db-offsite.service) / [`.timer`](../../scripts/gds/gds-db-offsite.timer)) + [`scripts/gds/db-backup-offsite.sh`](../../scripts/gds/db-backup-offsite.sh).
6
6
 
@@ -252,4 +252,4 @@ curl -s https://example.com/api/gds/public/progress | jq '.progress[0]'
252
252
  ## Cost
253
253
 
254
254
  - **Local nightly ([#412](https://example.com/builders#/task/412)):** $0/mo. `/var/backups/gds/` lives on the existing droplet disk; dumps are sub-MB; the systemd timer is free. The droplet is 67 GB total; years of dumps would not be a sizing concern.
255
- - **Offsite weekly ([#415](https://example.com/builders#/task/415)):** $5/mo flat — a DigitalOcean Space (250 GB + 1 TB transfer included). We retain only 4 sub-MB objects, so we use a rounding error of the tier. The $5/mo over Backblaze B2's ~$0 is a deliberate one-vendor / same-region simplicity choice — see [ADR 0025](../adr/<redacted>.md).
255
+ - **Offsite weekly ([#415](https://example.com/builders#/task/415)):** $5/mo flat — a DigitalOcean Space (250 GB + 1 TB transfer included). We retain only 4 sub-MB objects, so we use a rounding error of the tier. The $5/mo over Backblaze B2's ~$0 is a deliberate one-vendor / same-region simplicity choice — see [ADR 0025](../adr/0025-offsite-backup-vendor-digitalocean-spaces.md).
@@ -1,6 +1,6 @@
1
1
  # Recipe — deploying a Cloud Bongos instance on a pinned core (`git reset` → `npm ci`)
2
2
 
3
- > ADR [0108](../adr/<redacted>.md) §4 (configurable-root W4, task [#1884](https://example.com/builders#/task/1884)). How a **consumer instance** — one that installs `@bongos/core` as a versioned npm dependency rather than living in the monorepo — deploys. This is the target the live droplet deploy converts to; the reference implementation is [`scripts/deploy/deploy-instance.sh`](../../scripts/deploy/deploy-instance.sh).
3
+ > ADR [0108](../adr/0108-instance-composition-configurable-root.md) §4 (configurable-root W4, task [#1884](https://example.com/builders#/task/1884)). How a **consumer instance** — one that installs `@bongos/core` as a versioned npm dependency rather than living in the monorepo — deploys. This is the target the live droplet deploy converts to; the reference implementation is [`scripts/deploy/deploy-instance.sh`](../../scripts/deploy/deploy-instance.sh).
4
4
 
5
5
  ## The two models
6
6
 
@@ -33,6 +33,6 @@
33
33
 
34
34
  1. Install the script as the droplet's `~/deploy.sh` (the CI deploy key is forced-command-locked to `~/deploy.sh` — ADR 0043 — so it stays hand-installed, like `deploy-prod.sh`).
35
35
  2. Create a systemd unit for the instance: `ExecStart=/usr/bin/node <instanceRoot>/node_modules/@bongos/core/src/platform-server.js`, `WorkingDirectory=<instanceRoot>`, `Environment=PORT=… HOST=127.0.0.1 <PREFIX>_INSTANCE_ROOT=<instanceRoot>`.
36
- **`bongos serve` now writes exactly this unit for you** (plus the DB/migrate/health legs) — see [`server-bring-up.md`](server-bring-up.md) / [ADR 0169](../adr/<redacted>.md). Step 4 of the flow above ("restart the platform") is `systemctl restart bongos-<db>` once it has.
36
+ **`bongos serve` now writes exactly this unit for you** (plus the DB/migrate/health legs) — see [`server-bring-up.md`](server-bring-up.md) / [ADR 0169](../adr/0169-bongos-serve-server-bring-up.md). Step 4 of the flow above ("restart the platform") is `systemctl restart bongos-<db>` once it has.
37
37
  3. Set `INSTANCE_SERVICE=<unit>` + `PORT=<port>` in the deploy environment.
38
38
  4. Front it with TLS and point the origins at the real domain (see [self-host.md](self-host.md)).
@@ -1,6 +1,6 @@
1
1
  # Recipe — letting `bongos upgrade` restart the instance service unattended
2
2
 
3
- > [ADR 0279](../adr/<redacted>.md) · [task 1002884](https://cloudbongos.com/builders#/task/1002884). A core bump only counts once the **running process** is the new core, so `bongos upgrade` has to be able to restart the service without a human at a keyboard. This is what to do when it cannot.
3
+ > [ADR 0279](../adr/0279-an-upgrade-is-proven-by-the-served-version-not-the-health-check.md) · [task 1002884](https://cloudbongos.com/builders#/task/1002884). A core bump only counts once the **running process** is the new core, so `bongos upgrade` has to be able to restart the service without a human at a keyboard. This is what to do when it cannot.
4
4
 
5
5
  ## The symptom
6
6
 
@@ -84,6 +84,6 @@ curl -s https://<instance>/version
84
84
 
85
85
  ## Related
86
86
 
87
- - [ADR 0279](../adr/<redacted>.md) — why a health check cannot confirm an upgrade
88
- - [ADR 0136](../adr/<redacted>.md) §3 — the unattended subscription lane's health-gate + auto-rollback policy
87
+ - [ADR 0279](../adr/0279-an-upgrade-is-proven-by-the-served-version-not-the-health-check.md) — why a health check cannot confirm an upgrade
88
+ - [ADR 0136](../adr/0136-update-channel-subscription-policy.md) §3 — the unattended subscription lane's health-gate + auto-rollback policy
89
89
  - [`docs/recipes/ops-gotchas.md`](ops-gotchas.md) — the wider set of deploy traps
@@ -3,7 +3,7 @@
3
3
  > The one-command path from a freshly-cloned **standalone instance repo** (one whose
4
4
  > `config/branding.json` points at `http://localhost:<port>`) to a running, signed-in
5
5
  > instance on your Mac. This is the local counterpart of `bongos onboard` (which
6
- > stands an instance up in the **cloud**) — see [ADR 0149](../adr/<redacted>.md).
6
+ > stands an instance up in the **cloud**) — see [ADR 0149](../adr/0149-bongos-dev-local-launcher.md).
7
7
 
8
8
  ## TL;DR
9
9
 
@@ -81,4 +81,4 @@ the Client ID + secret to `~/.config/<configDir>/gds-github.json` as
81
81
  local database or server to run.
82
82
  - **Ready for a real host?** `bongos serve` runs this *same* boot path on a server —
83
83
  systemd-supervised, bind address derived from your public origin, no browser needed. See
84
- [`server-bring-up.md`](server-bring-up.md) ([ADR 0169](../adr/<redacted>.md)).
84
+ [`server-bring-up.md`](server-bring-up.md) ([ADR 0169](../adr/0169-bongos-serve-server-bring-up.md)).
@@ -1,8 +1,8 @@
1
1
  # Recipe - managed-settings SSH + browser-terminal on-ramps
2
2
 
3
- > **Task [#599](https://example.com/builders#/task/599) · [ADR 0031](../adr/<redacted>.md) §1.** This is the operator guide for distributing a locked Claude Desktop SSH connection to builders and for serving the browser web-terminal on the box. Read [builder-box-lifecycle.md](builder-box-lifecycle.md) first — this recipe assumes a box is already provisioned and running.
3
+ > **Task [#599](https://example.com/builders#/task/599) · [ADR 0031](../adr/0031-cloud-dev-environments-for-builders.md) §1.** This is the operator guide for distributing a locked Claude Desktop SSH connection to builders and for serving the browser web-terminal on the box. Read [builder-box-lifecycle.md](builder-box-lifecycle.md) first — this recipe assumes a box is already provisioned and running.
4
4
 
5
- > **Chromebook/browser path (ADR 0038 → [ADR 0040](../adr/<redacted>.md), [#760](https://example.com/builders#/task/760) / [#824](https://example.com/builders#/task/824)):** the box serves its own web terminal - `ttyd` bound to localhost, exposed via an outbound-only Cloudflare Tunnel - and the builder runs a NORMAL interactive `claude` inside it from any browser. Because there is a real human at a real browser-backed terminal, `/login`, workspace-trust, and Trusted-Devices enrollment all succeed (the things that made headless `claude rc` unworkable). **ADR 0040 narrows that terminal to a one-time launchpad:** the builder logs in there once, runs the in-session **`/remote-control`** slash command, and then drives the box from the Claude web/mobile app — the terminal is no longer their daily surface. **The SSH path (Mac/Windows) below is unaffected and works.**
5
+ > **Chromebook/browser path (ADR 0038 → [ADR 0040](../adr/0040-remote-control-default-browser-onramp.md), [#760](https://example.com/builders#/task/760) / [#824](https://example.com/builders#/task/824)):** the box serves its own web terminal - `ttyd` bound to localhost, exposed via an outbound-only Cloudflare Tunnel - and the builder runs a NORMAL interactive `claude` inside it from any browser. Because there is a real human at a real browser-backed terminal, `/login`, workspace-trust, and Trusted-Devices enrollment all succeed (the things that made headless `claude rc` unworkable). **ADR 0040 narrows that terminal to a one-time launchpad:** the builder logs in there once, runs the in-session **`/remote-control`** slash command, and then drives the box from the Claude web/mobile app — the terminal is no longer their daily surface. **The SSH path (Mac/Windows) below is unaffected and works.**
6
6
 
7
7
  ---
8
8
 
@@ -161,7 +161,7 @@ The `sshHostAllowlist: ["*.dev.example.com"]` entry prevents the builder from us
161
161
 
162
162
  ---
163
163
 
164
- ## Part 2 - Browser on-ramp: terminal launchpad -> Remote Control (Chromebook / any browser) - ADR 0038 -> [ADR 0040](../adr/<redacted>.md), [#760](https://example.com/builders#/task/760) / [#824](https://example.com/builders#/task/824)
164
+ ## Part 2 - Browser on-ramp: terminal launchpad -> Remote Control (Chromebook / any browser) - ADR 0038 -> [ADR 0040](../adr/0040-remote-control-default-browser-onramp.md), [#760](https://example.com/builders#/task/760) / [#824](https://example.com/builders#/task/824)
165
165
 
166
166
  ### How it works
167
167
 
@@ -1,10 +1,10 @@
1
1
  # Recipe — Builder memory backup + restore drill
2
2
 
3
- > **Filed by:** task [#281](https://example.com/builders#/task/281) (V3.R62), GDS-V3 criterion C8 ("memory is local-first, server-canonical on ship"). Depends on the server-side memory store ([#273](https://example.com/builders#/task/273) R54) and the DB backup pipeline ([#412](https://example.com/builders#/task/412) local nightly + [#415](https://example.com/builders#/task/415) weekly offsite). Companion to [`gds-db-backup.md`](gds-db-backup.md); vendor choice in [ADR 0025](../adr/<redacted>.md).
3
+ > **Filed by:** task [#281](https://example.com/builders#/task/281) (V3.R62), GDS-V3 criterion C8 ("memory is local-first, server-canonical on ship"). Depends on the server-side memory store ([#273](https://example.com/builders#/task/273) R54) and the DB backup pipeline ([#412](https://example.com/builders#/task/412) local nightly + [#415](https://example.com/builders#/task/415) weekly offsite). Companion to [`gds-db-backup.md`](gds-db-backup.md); vendor choice in [ADR 0025](../adr/0025-offsite-backup-vendor-digitalocean-spaces.md).
4
4
 
5
5
  ## Key decision — memory is backed up *as part of the full-DB backup*, not separately
6
6
 
7
- C8 makes each builder's local memory dir **server-canonical on ship**: `/builder-ship` upserts the builder's memory files into the `builder_memory` Postgres table ([#274](https://example.com/builders#/task/274) R55). Because that table lives in the same `example` database as everything else, **it is already captured by the full-DB backup pipeline** — there is deliberately **no separate `backup-memory.sh`**. A memory-only dump would duplicate what `pg_dump` already writes nightly and ship offsite weekly, and would be a second thing to keep in sync. One backup story, not two (same principle as [ADR 0025](../adr/<redacted>.md)'s retirement of the redundant [#7](https://example.com/builders#/task/7) cron).
7
+ C8 makes each builder's local memory dir **server-canonical on ship**: `/builder-ship` upserts the builder's memory files into the `builder_memory` Postgres table ([#274](https://example.com/builders#/task/274) R55). Because that table lives in the same `example` database as everything else, **it is already captured by the full-DB backup pipeline** — there is deliberately **no separate `backup-memory.sh`**. A memory-only dump would duplicate what `pg_dump` already writes nightly and ship offsite weekly, and would be a second thing to keep in sync. One backup story, not two (same principle as [ADR 0025](../adr/0025-offsite-backup-vendor-digitalocean-spaces.md)'s retirement of the redundant [#7](https://example.com/builders#/task/7) cron).
8
8
 
9
9
  So builder memory inherits both layers:
10
10
 
@@ -67,5 +67,5 @@ The first drill run **failed correctly**: the most recent nightly dump (04:02 UT
67
67
  ## See also
68
68
 
69
69
  - [`gds-db-backup.md`](gds-db-backup.md) — the full backup pipeline, install steps, and the general (non-memory-specific) restore drills.
70
- - [ADR 0025](../adr/<redacted>.md) — offsite vendor decision.
71
- - [ADR 0024](../adr/<redacted>.md) — the local-first / server-canonical memory model this backs up.
70
+ - [ADR 0025](../adr/0025-offsite-backup-vendor-digitalocean-spaces.md) — offsite vendor decision.
71
+ - [ADR 0024](../adr/0024-cloneable-repo-local-first-memory.md) — the local-first / server-canonical memory model this backs up.
@@ -1,6 +1,6 @@
1
1
  # Recipe — Memory sync conflicts: policy + clobber recovery
2
2
 
3
- > **Filed by:** task [#277](https://example.com/builders#/task/277) (V3.R58), GDS-V3 criterion C8. Documents the conflict policy chosen by the R04 spike ([ADR 0024](../adr/<redacted>.md) §3) and implemented across [#274](https://example.com/builders#/task/274) (push), [#275](https://example.com/builders#/task/275) (pull), [#276](https://example.com/builders#/task/276) (isolation). Recovery leans on the backup pipeline from [#281](https://example.com/builders#/task/281) ([`memory-backup.md`](memory-backup.md)).
3
+ > **Filed by:** task [#277](https://example.com/builders#/task/277) (V3.R58), GDS-V3 criterion C8. Documents the conflict policy chosen by the R04 spike ([ADR 0024](../adr/0024-cloneable-repo-local-first-memory.md) §3) and implemented across [#274](https://example.com/builders#/task/274) (push), [#275](https://example.com/builders#/task/275) (pull), [#276](https://example.com/builders#/task/276) (isolation). Recovery leans on the backup pipeline from [#281](https://example.com/builders#/task/281) ([`memory-backup.md`](memory-backup.md)).
4
4
 
5
5
  ## The policy in one line
6
6
 
@@ -93,6 +93,6 @@ sudo -u postgres dropdb example_recover && rm -f /tmp/recovered.txt
93
93
 
94
94
  ## See also
95
95
 
96
- - [ADR 0024](../adr/<redacted>.md) §3 — the decision + rejected alternatives.
96
+ - [ADR 0024](../adr/0024-cloneable-repo-local-first-memory.md) §3 — the decision + rejected alternatives.
97
97
  - [`memory-backup.md`](memory-backup.md) — backup cadence + the restore drill the recovery above relies on.
98
98
  - [`gds-db-backup.md`](gds-db-backup.md) — the underlying dump/offsite pipeline.
@@ -1,6 +1,6 @@
1
1
  # Multi-builder merge safety — audit + serialization model
2
2
 
3
- > **Deploy-mode note (current state).** This recipe documents the **`laptop`** merge path (operator merges `main` + SSHes the droplet). Since the 2026-06-13 cutover `config/deploy.json` is **`mode: ci`** — the merge + deploy run **server-side** (PR auto-merge + `.github/workflows/deploy-prod.yml`), and credential-less dev boxes ship via server-mediated publish ([ADR 0055](../adr/<redacted>.md)). The local-`main`-worktree + merge-lock model below applies only if `deploy.json` is reverted to `mode: laptop`.
3
+ > **Deploy-mode note (current state).** This recipe documents the **`laptop`** merge path (operator merges `main` + SSHes the droplet). Since the 2026-06-13 cutover `config/deploy.json` is **`mode: ci`** — the merge + deploy run **server-side** (PR auto-merge + `.github/workflows/deploy-prod.yml`), and credential-less dev boxes ship via server-mediated publish ([ADR 0055](../adr/0055-server-mediated-branch-publish.md)). The local-`main`-worktree + merge-lock model below applies only if `deploy.json` is reverted to `mode: laptop`.
4
4
 
5
5
  > **Task:** V3.R50 / [#269](https://example.com/builders#/task/269) (criterion **C6 — parallel-safe-under-load**).
6
6
  > **Question it answers:** when N>1 builders ship and merge concurrently, where do `ship.js` and `/merge-mode` assume "I am the only builder," and what serializes the shared state so they don't collide?
@@ -72,7 +72,7 @@ Behavior is pinned by [`tests/merge_lock.mjs`](../../tests/merge_lock.mjs) (auto
72
72
 
73
73
  ## Related
74
74
 
75
- - [ADR 0024](../adr/<redacted>.md) — multi-agent system (the reason N>1 builders exist).
75
+ - [ADR 0024](../adr/0024-multi-agent-system-architecture.md) — multi-agent system (the reason N>1 builders exist).
76
76
  - [#462](https://example.com/builders#/task/462) — the C4 auto-merge lock this task generalizes.
77
77
  - [#270](https://example.com/builders#/task/270) (V3.R51) — server-side worktree-name uniqueness (a sibling parallel-safety fix).
78
78
  - [#272](https://example.com/builders#/task/272) — the parallel-load smoke test that *exercises* this serialization under 5 simulated builders (the other open C6 task). Its **DB rank is R53** (the DB is king); the original planning-seed cross-ref text called it "R54", but the live rank renumbering settled it at R53/[#272](https://example.com/builders#/task/272).
@@ -28,7 +28,7 @@ Organized by topic, not chronology. New entries go in the matching section; crea
28
28
  ### Re-provisioning an EXISTING instance moves its `HOME`, orphaning any stored builder secrets
29
29
 
30
30
  - **Symptom:** after a re-provision, an instance that had builder API keys stored can no longer decrypt them. Nothing errors at startup — the instance comes up healthy and simply behaves as though no key was ever saved.
31
- - **Root cause:** task [1003369](https://cloudbongos.com/builders#/task/1003369) ([ADR 0281](../adr/<redacted>.md)) gives each instance its own unix account with `HOME=/var/lib/bongos-<slug>`. [`src/bongos/secret-box.js`](../../src/bongos/secret-box.js) keeps its master key at `~/.config/<configDir>/builder-secret.key`, so the key an instance wrote under the OLD shared home (`/home/lars/.config/…`) is no longer on its `HOME` path. `provisionMasterKey()` finds nothing, mints a fresh key, and every previously encrypted secret is now undecryptable ciphertext.
31
+ - **Root cause:** task [1003369](https://cloudbongos.com/builders#/task/1003369) ([ADR 0281](../adr/0281-an-instance-identity-is-its-own-unix-account-and-pg-role.md)) gives each instance its own unix account with `HOME=/var/lib/bongos-<slug>`. [`src/bongos/secret-box.js`](../../src/bongos/secret-box.js) keeps its master key at `~/.config/<configDir>/builder-secret.key`, so the key an instance wrote under the OLD shared home (`/home/lars/.config/…`) is no longer on its `HOME` path. `provisionMasterKey()` finds nothing, mints a fresh key, and every previously encrypted secret is now undecryptable ciphertext.
32
32
  - **Who this hits:** only a **re-provision of an instance that has already stored secrets**. A fresh standup has nothing to lose, and an instance whose `web.env` sets `BUILDER_SECRET_KEY` is unaffected — that env wins over the file.
33
33
  - **Fix (before the re-provision, one command as root):**
34
34
  ```bash
@@ -70,7 +70,7 @@ Organized by topic, not chronology. New entries go in the matching section; crea
70
70
 
71
71
  - **Symptom:** Caddy obtained the initial cert fine, then failed to renew at the 90-day mark — site went down.
72
72
  - **Root cause:** With Cloudflare proxy ON (orange cloud), CF intercepts port 80 at the edge and Caddy never sees the HTTP-01 challenge from Let's Encrypt. Renewal silently fails.
73
- - **Fix (already in place):** Replaced Let's Encrypt with a Cloudflare Origin Certificate (15-year cert at `/etc/caddy/origin.crt` + `.key`, explicit `tls` directive in Caddyfile). Eliminates the auto-renewal dependency for the CF↔origin leg. See [ADR 0003](../adr/<redacted>.md).
73
+ - **Fix (already in place):** Replaced Let's Encrypt with a Cloudflare Origin Certificate (15-year cert at `/etc/caddy/origin.crt` + `.key`, explicit `tls` directive in Caddyfile). Eliminates the auto-renewal dependency for the CF↔origin leg. See [ADR 0003](../adr/0003-cloudflare-origin-cert-over-letsencrypt.md).
74
74
  - **Why it bites:** The failure mode is silent for ~89 days, then catastrophic. Easy to think the site is "set and forget" when it is actually approaching a cliff.
75
75
 
76
76
  ### Deploying configs to `/etc/caddy/` requires staging through `~/`
@@ -249,7 +249,7 @@ Organized by topic, not chronology. New entries go in the matching section; crea
249
249
 
250
250
  - **Symptom:** the site is down for hours, but The Watch still shows 100% / "standing".
251
251
  - **Root cause:** `status.example.com` is served by the same Node process on the same droplet as the game, and the in-process poller (`src/bongos/uptime-poller.js`) probes `127.0.0.1`. When the droplet dies, the page dies with it and the poller writes **zero rows** — the gap renders as green. A monitor that lives inside the monitored thing cannot witness its own death.
252
- - **Fix:** measure availability from **outside** (the external GitHub-Actions prober — `.github/workflows/status-probe.yml`, task [#565](https://example.com/builders#/task/565)) and host the status page **off-box** (follow-up [#566](https://example.com/builders#/task/566)). See [ADR 0029](../adr/<redacted>.md) + Bongos learning `#35`.
252
+ - **Fix:** measure availability from **outside** (the external GitHub-Actions prober — `.github/workflows/status-probe.yml`, task [#565](https://example.com/builders#/task/565)) and host the status page **off-box** (follow-up [#566](https://example.com/builders#/task/566)). See [ADR 0029](../adr/0029-status-page-outage-resilience.md) + Bongos learning `#35`.
253
253
  - **Why it bites:** a status page that lies is worse than none — it actively reassures you while the product is on fire.
254
254
 
255
255
  ### The live status page is NOT served by the droplet — editing the status surface + deploying does nothing
@@ -268,7 +268,7 @@ Organized by topic, not chronology. New entries go in the matching section; crea
268
268
  ### `bypassPermissions` "still not available" even though the box was provisioned for it (task 2022)
269
269
 
270
270
  - **Symptom:** you reconnect to the browser terminal (or SSH) on a dev box and `claude` still stops for permission prompts, even though tasks [#1251](https://example.com/builders#/task/1251) and [#1314](https://example.com/builders#/task/1314) default every box to `bypassPermissions`.
271
- - **Root cause:** `otb-box-launch.sh` (behind `box-terminal.service`) only ever runs `claude` once — the first time it creates the tmux `otb` session. Every later connect just reattaches to that **same running process**. The `defaultMode=bypassPermissions` setting is written into `~/.claude/settings.json` by `box-source-fetch.sh`'s cron, on its own `*/10` schedule (and, on an already-provisioned box, only after that box's baked copy of the script has self-updated to even contain the fix). If the `otb` tmux session got created before that write landed — an older box, or a fresh box whose very first connect raced the first cron tick — `claude` started once in normal `auto` mode and is stuck there for the life of the box; reconnecting never re-launches it, so the fix never takes effect even once the setting is correct on disk. (Flagged as an open follow-up in [ADR 0104](../adr/<redacted>.md).)
271
+ - **Root cause:** `otb-box-launch.sh` (behind `box-terminal.service`) only ever runs `claude` once — the first time it creates the tmux `otb` session. Every later connect just reattaches to that **same running process**. The `defaultMode=bypassPermissions` setting is written into `~/.claude/settings.json` by `box-source-fetch.sh`'s cron, on its own `*/10` schedule (and, on an already-provisioned box, only after that box's baked copy of the script has self-updated to even contain the fix). If the `otb` tmux session got created before that write landed — an older box, or a fresh box whose very first connect raced the first cron tick — `claude` started once in normal `auto` mode and is stuck there for the life of the box; reconnecting never re-launches it, so the fix never takes effect even once the setting is correct on disk. (Flagged as an open follow-up in [ADR 0104](../adr/0104-trust-gds-api-channel-in-auto-mode.md).)
272
272
  - **Fix:** `otb-box-launch.sh` now asserts `defaultMode=bypassPermissions` itself, synchronously, right before it creates a **new** `otb` tmux session — so a fresh session never depends on cron timing. This prevents the race going forward but does **not** repair a box whose `otb` session is already running in the wrong mode: for that, from an SSH/browser-terminal shell run `tmux kill-session -t otb` then reconnect (the launcher creates a fresh session and picks up the corrected setting immediately). Killing the session only drops the terminal pane — it does not touch `/workspace` or in-flight git state.
273
273
  - **Why it bites:** every layer *looks* fixed — `~/.claude/settings.json` has the right value, `IS_SANDBOX=1` is set — because you're inspecting the box's filesystem, not the already-running process that never re-read it.
274
274
 
@@ -33,7 +33,7 @@ curl -sS -X PATCH -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: applicat
33
33
  -d '{"parallel_safe": true}' https://example.com/api/gds/tasks/<id>
34
34
  ```
35
35
 
36
- In parallel mode each worker stops at `confirmed` (verified, not yet paid — [ADR 0120](../adr/<redacted>.md) books credits at land) and the runner lands the merges **one at a time** — concurrent merges to `main` are never allowed. Credits land as each merge completes.
36
+ In parallel mode each worker stops at `confirmed` (verified, not yet paid — [ADR 0120](../adr/0120-pay-on-land-and-builder-owned-rebase-gate.md) books credits at land) and the runner lands the merges **one at a time** — concurrent merges to `main` are never allowed. Credits land as each merge completes.
37
37
 
38
38
  ## Reading the morning report
39
39
 
@@ -2,13 +2,13 @@
2
2
 
3
3
  > **This is one leg of three.** For how a change to Cloud Bongos actually reaches a live instance — and why merging to `main` ships nothing on its own — start at [the core release pipeline](core-release-pipeline.md).
4
4
  >
5
- > Implements [ADR 0100 §1](../adr/<redacted>.md) (the two-repo instance model). This is **R84**, the first step of the `R84 → R85 → R86` spine: package the core → stand a downstream instance up on a pinned core → make `bongos upgrade` a real update channel. Tooling: [`scripts/gds/package-core.js`](../../scripts/gds/package-core.js) (`bongos package-core`).
5
+ > Implements [ADR 0100 §1](../adr/0100-two-repo-instance-model.md) (the two-repo instance model). This is **R84**, the first step of the `R84 → R85 → R86` spine: package the core → stand a downstream instance up on a pinned core → make `bongos upgrade` a real update channel. Tooling: [`scripts/gds/package-core.js`](../../scripts/gds/package-core.js) (`bongos package-core`).
6
6
  >
7
- > **Real installable npm package ([ADR 0108](../adr/<redacted>.md) §2, task 1882/W2, shipped):** the artifact is `package/`-rooted (the npm convention `npm install ./x.tgz` requires) and carries a synthesized `package.json` — `name: "@bongos/core"`, `version` = `CORE_VERSION`, `main: "src/platform-server.js"`, `exports` for the default entry (`buildPlatformApp`) plus `./serve-internal` (`mountInternalSurfaces`) and `./module-api`, `bin: "bongos"` — and a **pruned** `package-lock.json` (express + pg's own transitive closure only, resolved offline from the source lockfile — no colyseus/phaser/sharp/discord.js). Both files are synthesized fresh, never copied verbatim from the source repo's game-heavy `package.json`. `resolveCoreRoot()`/`resolveInstanceRoot()` ([`src/instance-config.js`](../../src/instance-config.js), W1/task 1881) are what a consumer's own code routes through once installed.
7
+ > **Real installable npm package ([ADR 0108](../adr/0108-instance-composition-configurable-root.md) §2, task 1882/W2, shipped):** the artifact is `package/`-rooted (the npm convention `npm install ./x.tgz` requires) and carries a synthesized `package.json` — `name: "@bongos/core"`, `version` = `CORE_VERSION`, `main: "src/platform-server.js"`, `exports` for the default entry (`buildPlatformApp`) plus `./serve-internal` (`mountInternalSurfaces`) and `./module-api`, `bin: "bongos"` — and a **pruned** `package-lock.json` (express + pg's own transitive closure only, resolved offline from the source lockfile — no colyseus/phaser/sharp/discord.js). Both files are synthesized fresh, never copied verbatim from the source repo's game-heavy `package.json`. `resolveCoreRoot()`/`resolveInstanceRoot()` ([`src/instance-config.js`](../../src/instance-config.js), W1/task 1881) are what a consumer's own code routes through once installed.
8
8
 
9
9
  ## What the artifact is
10
10
 
11
- A Cloud Bongos *instance* can be its **own repository** that installs a **pinned version** of the Cloud Bongos **core** — the portable methodology + platform + neutral branding — and layers its own content, branding, and modules on top. "The core" is not re-defined here: it is exactly the subtree [`isPublishable()`](../../scripts/gds/publish-manifest.js) already defines ([ADR 0098](../adr/<redacted>.md)).
11
+ A Cloud Bongos *instance* can be its **own repository** that installs a **pinned version** of the Cloud Bongos **core** — the portable methodology + platform + neutral branding — and layers its own content, branding, and modules on top. "The core" is not re-defined here: it is exactly the subtree [`isPublishable()`](../../scripts/gds/publish-manifest.js) already defines ([ADR 0098](../adr/0098-public-mirror-publish-manifest.md)).
12
12
 
13
13
  `bongos package-core` produces three things in `dist/` (git-ignored — the artifact is a build product, not committed):
14
14
 
@@ -20,7 +20,7 @@ A Cloud Bongos *instance* can be its **own repository** that installs a **pinned
20
20
 
21
21
  The version is the **platform version** — `CORE_VERSION` from [`src/module-api.js`](../../src/module-api.js), the same coordinate the module loader and `bongos upgrade` compare against ([#1203](https://example.com/builders#/task/1203)). That shared coordinate is what keeps the spine coherent: a module pinned to `^core_contract` is guaranteed to load against the packaged core.
22
22
 
23
- Every file is **redacted** through the same fail-closed pipeline the public mirror uses ([ADR 0099](../adr/<redacted>.md)): instance literals + public IPs are stripped, a secret backstop runs, and if *any* residual leak survives the packager **produces nothing** (`dist/` is never touched). So a downstream repo never inherits the source instance's identity or secrets — it gets a neutral core.
23
+ Every file is **redacted** through the same fail-closed pipeline the public mirror uses ([ADR 0099](../adr/0099-delayed-redacted-mirror-export.md)): instance literals + public IPs are stripped, a secret backstop runs, and if *any* residual leak survives the packager **produces nothing** (`dist/` is never touched). So a downstream repo never inherits the source instance's identity or secrets — it gets a neutral core.
24
24
 
25
25
  ## Produce it
26
26
 
@@ -59,6 +59,6 @@ The manifest's `files[]` carries the same `{ path, mode, sha256 }` triples, so t
59
59
 
60
60
  ## Boundaries + relation to the mirror
61
61
 
62
- - **Not the public mirror.** The delayed, redacted, ~6-month-lagged public mirror ([ADR 0099](../adr/<redacted>.md)) is the open-source surface. This artifact is a *current*, versioned unit for **dependency consumption** by a sister repo — no lag. Both reuse the same `isPublishable()` selection and the same redaction; `package-core.js` imports the mirror's `redactBlob` so the redaction logic is defined once.
63
- - **Per-repo Bongos.** Each instance runs its own database, tasks, builders, and credits ([ADR 0100 §3](../adr/<redacted>.md)). Packaging the core moves *code*, never work-tracking state.
62
+ - **Not the public mirror.** The delayed, redacted, ~6-month-lagged public mirror ([ADR 0099](../adr/0099-delayed-redacted-mirror-export.md)) is the open-source surface. This artifact is a *current*, versioned unit for **dependency consumption** by a sister repo — no lag. Both reuse the same `isPublishable()` selection and the same redaction; `package-core.js` imports the mirror's `redactBlob` so the redaction logic is defined once.
63
+ - **Per-repo Bongos.** Each instance runs its own database, tasks, builders, and credits ([ADR 0100 §3](../adr/0100-two-repo-instance-model.md)). Packaging the core moves *code*, never work-tracking state.
64
64
  - **The single-checkout instance model is not deprecated** — it stays the cheaper shape for a quick reskin (cloudbongos.com). Two-repo is the destination for a project that wants to be its own thing and pull core updates on its own schedule.
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **This is one leg of three.** For the whole path from a change on core `main` to a live instance — and for when publishing to npm is *not* what moves an instance — start at [the core release pipeline](core-release-pipeline.md).
4
4
  >
5
- > Implements [ADR 0134](../adr/<redacted>.md), **core half only**. Pre-launch, `@bongos/core` publishes as a **private, scoped** npm package on the owner's paid `bongos` npm org (the canonical brand); at launch it flips to public. The daily command is `bongos` regardless of package name.
5
+ > Implements [ADR 0134](../adr/0134-private-first-npm-distribution.md), **core half only**. Pre-launch, `@bongos/core` publishes as a **private, scoped** npm package on the owner's paid `bongos` npm org (the canonical brand); at launch it flips to public. The daily command is `bongos` regardless of package name.
6
6
  >
7
7
  > **`@bongos/client` is no longer part of this.** It was published once (2026-07-07, 0.0.2), never updated while the API moved 500+ core versions, and had **zero** consumers the whole time — every consumer vendors a copy instead. The owner removed it from npm on 2026-09-09; ADR 0134's client half is superseded ([task 1003742](https://cloudbongos.com/builders#/task/1003742)). The generated client still exists and still regenerates — it is simply not a package.
8
8
  >
@@ -52,13 +52,13 @@ npm pack ./clients/bongos-client --dry-run # token-free content preview
52
52
  npm publish ./clients/bongos-client # real (publishConfig makes it restricted; needs npm login)
53
53
  ```
54
54
 
55
- ## Cutting a core release (the policy — [ADR 0161](../adr/<redacted>.md), superseding ADR 0137)
55
+ ## Cutting a core release (the policy — [ADR 0161](../adr/0161-publish-on-merge.md), superseding ADR 0137)
56
56
 
57
- **Publishing is automatic on merge** as of 2026-08-08: the `publish` workflow rides behind the required `unit` check, auto-bumps a patch when nobody bumped, builds through the fail-closed no-leak gate, publishes, and tags — see the workflow header (`.github/workflows/publish.yml`) and ADR 0161. It ships inert until the owner arms it (repo variable `PUBLISH_ON_MERGE=1` + secrets `NPM_TOKEN`, `RELEASE_PUSH_TOKEN`). A **minor/major bump stays a human in-task edit**. The update subscription ([ADR 0136](../adr/<redacted>.md)) consumes whatever is published, on its next sweep.
57
+ **Publishing is automatic on merge** as of 2026-08-08: the `publish` workflow rides behind the required `unit` check, auto-bumps a patch when nobody bumped, builds through the fail-closed no-leak gate, publishes, and tags — see the workflow header (`.github/workflows/publish.yml`) and ADR 0161. It ships inert until the owner arms it (repo variable `PUBLISH_ON_MERGE=1` + secrets `NPM_TOKEN`, `RELEASE_PUSH_TOKEN`). A **minor/major bump stays a human in-task edit**. The update subscription ([ADR 0136](../adr/0136-update-channel-subscription-policy.md)) consumes whatever is published, on its next sweep.
58
58
 
59
59
  The steps below remain as the **manual fallback** (lane disarmed, npm outage, or a deliberate out-of-band release):
60
60
 
61
- 1. **Bump `CORE_VERSION`** in [`src/module-api.js`](../../src/module-api.js) (semver; a **patch** for a fix, **minor** for additive surface — a **major** is a deliberate, human-only event) and append an entry to the release ledger [`docs/module-api-changelog.md`](../module-api-changelog.md) in the same commit ([ADR 0203](../adr/<redacted>.md) moved that ledger out of `module-api.js`). This bump is a normal claimed task, not a release-tool side effect — the version's provenance stays in the git history + ledger.
61
+ 1. **Bump `CORE_VERSION`** in [`src/module-api.js`](../../src/module-api.js) (semver; a **patch** for a fix, **minor** for additive surface — a **major** is a deliberate, human-only event) and append an entry to the release ledger [`docs/module-api-changelog.md`](../module-api-changelog.md) in the same commit ([ADR 0203](../adr/0203-doorway-changelog-out-of-module-api.md) moved that ledger out of `module-api.js`). This bump is a normal claimed task, not a release-tool side effect — the version's provenance stays in the git history + ledger.
62
62
  2. **Publish** (owner, from a clean checkout of the released commit):
63
63
  ```sh
64
64
  node scripts/gds/package-core.js --publish # DRY-RUN: runs the fail-closed no-leak gate, previews @bongos/core@<version>
@@ -69,7 +69,7 @@ The steps below remain as the **manual fallback** (lane disarmed, npm outage, or
69
69
  3. **Tag the release** (optional but recommended — the deliberate, auditable marker): `git tag core-v<version> && git push origin core-v<version>`. The tag documents intent; it triggers no CI.
70
70
  4. **Done.** Subscribed instances on the `patch`/`minor` channel take it automatically on their next routine sweep; `pinned` instances wait for a manual `bongos upgrade`. A stale (un-bumped) version is rejected by npm as a duplicate — a natural guard.
71
71
 
72
- > **Automating this** (a tag-triggered CI publish) is deferred to the managed-fleet epic ([#1948](https://example.com/builders#/task/1948)); revisit when the manual step becomes a real bottleneck. See [ADR 0137](../adr/<redacted>.md) "When to revisit".
72
+ > **Automating this** (a tag-triggered CI publish) is deferred to the managed-fleet epic ([#1948](https://example.com/builders#/task/1948)); revisit when the manual step becomes a real bottleneck. See [ADR 0137](../adr/0137-upstream-publish-policy-manual-owner-gated.md) "When to revisit".
73
73
 
74
74
  ## Install a private package (any consumer machine or instance)
75
75
 
@@ -10,13 +10,13 @@ How the `search_chunks` index (the recall layer, [ADR 0060](../adr/0060-gds-retr
10
10
 
11
11
  - **Delta-driven.** Each chunk's `content_hash` (sha256 of its body) is the change key. The upsert's `ON CONFLICT … DO UPDATE … WHERE content_hash IS DISTINCT FROM EXCLUDED.content_hash` makes an unchanged chunk a **no-op** (no row rewrite). A re-run over an unchanged tree writes nothing.
12
12
  - **Prunes shrinkage.** If a file loses sections, chunks beyond the new count are deleted; if a file is removed from the tree entirely, all its chunks are deleted (`source_kind='doc' AND source_ref NOT IN (present)`).
13
- - **Scopes by rank.** Most docs are `min_rank='xenos'` (shared). Read-sensitive documentation surfaces are tagged `min_rank='metic'` so a sub-Metic search can never surface them ([ADR 0060](../adr/0060-gds-retrieval-layer.md) §6 / [ADR 0043](../adr/<redacted>.md)). The metic set is curated in `SENSITIVE_DOC_GLOBS`: `docs/canonical-permissions.md`, `docs/security/`, `docs/audits/`, and the two trust-boundary ADRs (0016, 0043). **`CLAUDE.md` is deliberately `xenos`** — it's write-protected but the universal read-public onboarding index. Docs are never owner-scoped (`owner_builder_id` stays NULL); per-builder private content is the DB-prose ingester's job (memory rows).
13
+ - **Scopes by rank.** Most docs are `min_rank='xenos'` (shared). Read-sensitive documentation surfaces are tagged `min_rank='metic'` so a sub-Metic search can never surface them ([ADR 0060](../adr/0060-gds-retrieval-layer.md) §6 / [ADR 0043](../adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md)). The metic set is curated in `SENSITIVE_DOC_GLOBS`: `docs/canonical-permissions.md`, `docs/security/`, `docs/audits/`, and the two trust-boundary ADRs (0016, 0043). **`CLAUDE.md` is deliberately `xenos`** — it's write-protected but the universal read-public onboarding index. Docs are never owner-scoped (`owner_builder_id` stays NULL); per-builder private content is the DB-prose ingester's job (memory rows).
14
14
 
15
15
  ## When it runs
16
16
 
17
17
  A **non-blocking step in the prod deploy** ([`scripts/deploy/deploy-prod.sh`](../../scripts/deploy/deploy-prod.sh), mirrored in the droplet's hand-maintained `~/deploy.sh`), after the code update + migrations + healthz, where the new markdown and the DB are both on disk. It's wrapped `timeout 60 … || echo "…deploy unaffected"` — **an ingest failure never fails a deploy**; the next deploy (or a manual run) catches up.
18
18
 
19
- > ⚠️ `scripts/deploy/deploy-prod.sh` is a **byte-faithful mirror** of the droplet's `~/deploy.sh`, which is **hand-maintained and NOT auto-installed** (the ci deploy key is forced-command-locked — [ADR 0042](../adr/<redacted>.md)/[0043](../adr/<redacted>.md)). When you change the mirror, **re-apply the same edit to `~/deploy.sh` on the droplet by hand** (`ssh lars@REDACTED_IP`), or the deploy hook won't actually run there. (Same caveat as the [prod deploy-script mirror](../../docs/recipes/ops-gotchas.md) note.)
19
+ > ⚠️ `scripts/deploy/deploy-prod.sh` is a **byte-faithful mirror** of the droplet's `~/deploy.sh`, which is **hand-maintained and NOT auto-installed** (the ci deploy key is forced-command-locked — [ADR 0042](../adr/0042-builder-self-deploy-ci-auto-merge.md)/[0043](../adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md)). When you change the mirror, **re-apply the same edit to `~/deploy.sh` on the droplet by hand** (`ssh lars@REDACTED_IP`), or the deploy hook won't actually run there. (Same caveat as the [prod deploy-script mirror](../../docs/recipes/ops-gotchas.md) note.)
20
20
 
21
21
  ## Operating it
22
22
 
@@ -39,7 +39,7 @@ Output reports `inserted / updated / unchanged / pruned / deleted_sources_chunks
39
39
 
40
40
  `node scripts/gds/search-ingest-db.js` indexes the prose that lives in the DB, not in git, as `source_kind='db'`: task descriptions + value summaries (`task:<id>`), learnings (`learning:<id>`), idea inbox (`idea:<id>`), done-when criteria (`criterion:<id>`), blockers (`blocker:<id>`), session-log notes (`session_log:<id>`), grade notes (`grade:<id>`), per-builder memory (`memory:<builder>:<path>`), and recent git commit subjects (`commit:<sha>`). Same delta-by-content_hash + prune-vanished behavior as the repo-md ingester.
41
41
 
42
- Security ([ADR 0060](../adr/0060-gds-retrieval-layer.md) §6 / [ADR 0016](../adr/<redacted>.md) / [ADR 0022](../adr/0022-secrets-policy.md)):
42
+ Security ([ADR 0060](../adr/0060-gds-retrieval-layer.md) §6 / [ADR 0016](../adr/0016-trust-boundary-server-enforced-permissions.md) / [ADR 0022](../adr/0022-secrets-policy.md)):
43
43
 
44
44
  - **`builder_memory` is owner-scoped** — each chunk carries `owner_builder_id`, so a builder's private memory only ever surfaces to that builder (the search route's owner filter, [#950](https://example.com/builders#/task/950)).
45
45
  - **`security_sensitive` tasks are tagged `min_rank='metic'`**.