@bongos/core 1.19.714 → 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.
- package/.bongos-core.json +488 -413
- package/.claude/skills/backlog-review/SKILL.md +3 -3
- package/.claude/skills/blocker-review/SKILL.md +1 -1
- package/.claude/skills/blocker-solve/SKILL.md +2 -2
- package/.claude/skills/builder-reauth/SKILL.md +1 -1
- package/.claude/skills/builder-redteam/SKILL.md +1 -1
- package/.claude/skills/builder-ship/SKILL.md +1 -1
- package/.claude/skills/builder-start/SKILL.md +1 -1
- package/.claude/skills/design/SKILL.md +2 -2
- package/.claude/skills/feedback/SKILL.md +1 -1
- package/.claude/skills/goal-create/SKILL.md +1 -1
- package/.claude/skills/goal-review/SKILL.md +2 -2
- package/.claude/skills/idea-triage/SKILL.md +5 -5
- package/.claude/skills/merge-mode/SKILL.md +4 -4
- package/.claude/skills/new-project/SKILL.md +17 -17
- package/.claude/skills/planning-session/SKILL.md +11 -11
- package/.claude/skills/recall/SKILL.md +2 -2
- package/.claude/skills/strand-fix/SKILL.md +1 -1
- package/.devcontainer/README.md +2 -2
- package/CONTRIBUTING.md +2 -2
- package/GOVERNANCE.md +4 -4
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +4 -0
- package/clients/bongos-client/index.cjs +4 -0
- package/clients/bongos-client/index.d.ts +5 -0
- package/clients/bongos-client/index.mjs +4 -0
- package/config/branding.neutral.json +4 -2
- package/docs/adr/0001-stack-choice-single-vps.md +2 -2
- package/docs/adr/0002-digitalocean-over-hetzner.md +1 -1
- package/docs/adr/0008-google-chat-oauth-user-auth.md +1 -1
- package/docs/adr/0009-autotile-architecture.md +1 -1
- package/docs/adr/0011-terrain-id-rendering-model.md +3 -3
- package/docs/adr/0013-paths-as-object-overlays-with-autotile-dispatch.md +1 -1
- package/docs/adr/0014-families-canonical-over-vocabulary.md +1 -1
- package/docs/adr/0015-task-dependencies-and-auto-promotion.md +1 -1
- package/docs/adr/0016-trust-boundary-server-enforced-permissions.md +1 -1
- package/docs/adr/0018-three-rank-model-goes-live.md +3 -3
- package/docs/adr/0020-security-model-public-stub.md +9 -9
- package/docs/adr/0021-per-builder-skill-model-preferences.md +2 -2
- package/docs/adr/0022-secrets-policy.md +5 -5
- package/docs/adr/0024-cloneable-repo-local-first-memory.md +3 -3
- package/docs/adr/0024-multi-agent-system-architecture.md +10 -10
- package/docs/adr/0025-offsite-backup-vendor-digitalocean-spaces.md +1 -1
- package/docs/adr/0025-structured-criterion-task-link.md +1 -1
- package/docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md +13 -13
- package/docs/adr/0027-bfg-session-inefficiency-evaluator.md +14 -14
- package/docs/adr/0029-status-page-outage-resilience.md +1 -1
- package/docs/adr/0030-builders-hall-live-updates.md +1 -1
- package/docs/adr/0031-cloud-dev-environments-for-builders.md +7 -7
- package/docs/adr/0032-discord-mirror-of-gds.md +3 -3
- package/docs/adr/0033-discord-bot-service-principal.md +4 -4
- package/docs/adr/0034-thetes-graduated-newcomer-rank.md +1 -1
- package/docs/adr/0035-builder-onboarding-three-paths.md +4 -4
- package/docs/adr/0036-builders-subdomain-and-ui-reorg.md +1 -1
- package/docs/adr/0037-discord-channel-management.md +1 -1
- package/docs/adr/0038-chromebook-ttyd-cloudflare-tunnel.md +5 -5
- package/docs/adr/0039-setup-first-onboarding-ux.md +6 -6
- package/docs/adr/0040-remote-control-default-browser-onramp.md +3 -3
- package/docs/adr/0041-temporary-grader-bypass-killswitch.md +2 -2
- package/docs/adr/0042-builder-self-deploy-ci-auto-merge.md +5 -5
- package/docs/adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md +2 -2
- package/docs/adr/0044-mediterranean-palette-replacement.md +1 -1
- package/docs/adr/0044-per-box-live-game-preview.md +1 -1
- package/docs/adr/0046-sandbox-first-review-gate.md +1 -1
- package/docs/adr/0047-discord-bugs-intake-anti-abuse.md +1 -1
- package/docs/adr/0049-split-parallel-safety-contract.md +1 -1
- package/docs/adr/0050-device-flow-admission-invite-gated-by-default.md +2 -2
- package/docs/adr/0051-full-session-transcript-corpus.md +2 -2
- package/docs/adr/0052-sandbox-for-everyone-game-only-preview.md +1 -1
- package/docs/adr/0053-scoped-dev-box-session.md +1 -1
- package/docs/adr/0054-session-token-reward-cost-plus.md +7 -7
- package/docs/adr/0055-server-mediated-branch-publish.md +2 -2
- package/docs/adr/0056-prod-deploy-script-mirror-and-healthcheck-retry.md +3 -3
- package/docs/adr/0057-container-cost-ledger.md +1 -1
- package/docs/adr/0057-discord-archon-approval-channels.md +2 -2
- package/docs/adr/0058-automatic-gate-surface-gatekeeper.md +6 -6
- package/docs/adr/0059-single-approval-remove-devbox-approval-gate.md +11 -11
- package/docs/adr/0060-gds-retrieval-layer.md +3 -3
- package/docs/adr/0061-context-layer-decomposition.md +2 -2
- package/docs/adr/0062-medusa-instance-model-decoupling.md +5 -5
- package/docs/adr/0063-generated-repo-map-symbol-skeleton.md +2 -2
- package/docs/adr/0064-rename-medusa-to-cloud-bongos.md +3 -3
- package/docs/adr/0065-agpl-nonprofit-ai-first-governance.md +5 -5
- package/docs/adr/0066-generated-file-map-sections.md +2 -2
- package/docs/adr/0067-session-start-fast-forward-pull.md +1 -1
- package/docs/adr/0068-shared-art-key-for-newcomers.md +1 -1
- package/docs/adr/0069-hall-live-channel-sse-decouple.md +3 -3
- package/docs/adr/0070-deterministic-session-card-delivery.md +1 -1
- package/docs/adr/0071-box-confirm-before-destroyed-and-drift-reconcile.md +2 -2
- package/docs/adr/0072-bongos-app-mac-signed-first-windows-deferred.md +2 -2
- package/docs/adr/0072-dev-box-code-staleness-visibility.md +2 -2
- package/docs/adr/0073-builder-needs-signal-and-byok-gemini-key.md +3 -3
- package/docs/adr/0073-secrets-scan-exclude-uri-detector.md +2 -2
- package/docs/adr/0076-in-session-deterministic-compaction.md +2 -2
- package/docs/adr/0077-content-addressed-llm-cache.md +2 -2
- package/docs/adr/0078-deterministic-first-cron.md +3 -3
- package/docs/adr/0079-value-gated-autonomous-engagement.md +2 -2
- package/docs/adr/0080-llm-cache-api-transport-and-trust-model.md +3 -3
- package/docs/adr/0081-tool-agnostic-design-layer.md +3 -3
- package/docs/adr/0082-server-side-merge-conflict-auto-resolution.md +2 -2
- package/docs/adr/0083-modular-architecture-strangler-build-plan.md +3 -3
- package/docs/adr/0085-remove-default-per-builder-spend-cap.md +2 -2
- package/docs/adr/0086-goal-scoped-work-hierarchy.md +15 -15
- package/docs/adr/0087-bongos-app-architecture-and-handoff-contract.md +5 -5
- package/docs/adr/0087-compete-on-governance-not-tooling-cursor.md +1 -1
- package/docs/adr/0088-consistent-character-generative-animation.md +5 -5
- package/docs/adr/0089-modular-multi-model-adversarial-grader.md +15 -15
- package/docs/adr/0090-metic-task-authoring.md +8 -8
- package/docs/adr/0091-bounding-the-kernel-and-db-carve.md +3 -3
- package/docs/adr/0092-hosting-module-and-on-prem-target.md +11 -11
- package/docs/adr/0093-tranche-2-core-carve-sequence.md +5 -5
- package/docs/adr/0094-repo-atlas-self-drawing-codebase-map.md +1 -1
- package/docs/adr/0095-borrowed-memory-and-retrieval-concepts.md +6 -6
- package/docs/adr/0095-cross-agent-context-management.md +5 -5
- package/docs/adr/0096-require-reward-before-workable.md +5 -5
- package/docs/adr/0097-one-active-claim-per-session-and-worktree-binding.md +2 -2
- package/docs/adr/0097-retroactive-reward-backfill.md +4 -4
- package/docs/adr/0098-public-mirror-publish-manifest.md +3 -3
- package/docs/adr/0099-delayed-redacted-mirror-export.md +1 -1
- package/docs/adr/0100-two-repo-instance-model.md +6 -6
- package/docs/adr/0101-goal-hierarchy-phase-5-judge-membership-reward.md +9 -9
- package/docs/adr/0102-finish-bounding-the-kernel.md +1 -1
- package/docs/adr/0103-core-first-extraction-cloud-bongos-trunk.md +6 -6
- package/docs/adr/0103-gdsv4-bongos-consolidation.md +3 -3
- package/docs/adr/0104-trust-gds-api-channel-in-auto-mode.md +3 -3
- package/docs/adr/0105-instance-seed-migrations-out-of-core.md +2 -2
- package/docs/adr/0106-goal-owner-manager-authority.md +2 -2
- package/docs/adr/0107-module-upstreaming-contribution-to-core-catalog.md +6 -6
- package/docs/adr/0108-instance-composition-configurable-root.md +6 -6
- package/docs/adr/0109-self-describing-openapi-and-hosted-docs.md +3 -3
- package/docs/adr/0110-untrack-whole-file-generated-nav-docs.md +1 -1
- package/docs/adr/0111-instance-hosting-provisioning-module.md +18 -18
- package/docs/adr/0112-private-goals-invitations-join-requests.md +7 -7
- package/docs/adr/0113-sandbox-studio-descope-superseded-by-0044-0052.md +1 -1
- package/docs/adr/0114-instance-docs-discovery-contract.md +4 -4
- package/docs/adr/0115-scheduled-routines-portability.md +1 -1
- package/docs/adr/0117-api-versioning-and-deprecation-policy.md +1 -1
- package/docs/adr/0118-api-contract-source-of-truth-code-first.md +1 -1
- package/docs/adr/0120-pay-on-land-and-builder-owned-rebase-gate.md +2 -2
- package/docs/adr/0121-greenfield-vs-brownfield-onboarding-adopt-existing-repo.md +1 -1
- package/docs/adr/0122-onboarding-diagram-renders-deploy-rendered-off-git.md +3 -3
- package/docs/adr/0123-box-idle-sweep-autosave-before-destroy.md +1 -1
- package/docs/adr/0124-typed-api-response-bodies.md +2 -2
- package/docs/adr/0125-control-plane-scaffolds-standalone-instance-repo.md +2 -2
- package/docs/adr/0126-dedicated-cloudbongos-control-plane-droplet.md +3 -3
- package/docs/adr/0127-cross-box-fleet-observability.md +1 -1
- package/docs/adr/0128-provisioning-runner-privilege-and-db-auth-model.md +3 -3
- package/docs/adr/0129-cloudbongos-control-plane-pull-deploy.md +4 -4
- package/docs/adr/0130-provision-remote-exec-over-ssh.md +4 -4
- package/docs/adr/0131-rank-scoped-skill-visibility.md +2 -2
- package/docs/adr/0132-cohost-fleet-control-plane-migration.md +2 -2
- package/docs/adr/0133-github-app-manifest-onboarding-signin.md +1 -1
- package/docs/adr/0134-private-first-npm-distribution.md +3 -3
- package/docs/adr/0135-module-upstream-submission-interim-queue.md +1 -1
- package/docs/adr/0136-update-channel-subscription-policy.md +2 -2
- package/docs/adr/0137-upstream-publish-policy-manual-owner-gated.md +6 -6
- package/docs/adr/0138-bundled-module-deps-declared-per-module.md +4 -4
- package/docs/adr/0142-project-context-is-prose-only.md +2 -2
- package/docs/adr/0143-onboarding-repo-picker-oauth-scope.md +2 -2
- package/docs/adr/0144-devbox-rehome-onto-cloudbongos-plane.md +2 -2
- package/docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md +2 -2
- package/docs/adr/0146-configurable-reward-mode-cost-plus-only.md +4 -4
- package/docs/adr/0147-standalone-live-docs-regen.md +1 -1
- package/docs/adr/0149-bongos-dev-local-launcher.md +1 -1
- package/docs/adr/0150-box-first-boot-bringup-vendored-instances.md +3 -3
- package/docs/adr/0151-governance-permissions-as-atom-ranks-as-roles.md +20 -20
- package/docs/adr/0152-landing-gate-served-by-the-core-app.md +2 -2
- package/docs/adr/0152-metic-task-abandonment.md +7 -7
- package/docs/adr/0153-sequential-chain-runner.md +1 -1
- package/docs/adr/0154-goal-owner-criterion-authoring.md +7 -7
- package/docs/adr/0155-adopt-private-repo-widen-oauth-scope.md +2 -2
- package/docs/adr/0156-user-set-display-name-wins.md +1 -1
- package/docs/adr/0157-archon-is-rank-and-identity-only.md +10 -10
- package/docs/adr/0158-choke-point-verdict-taxonomy.md +1 -1
- package/docs/adr/0159-merge-gate-reconciliation.md +1 -1
- package/docs/adr/0160-main-audit-repo-verifiable-caller.md +1 -1
- package/docs/adr/0161-publish-on-merge.md +2 -2
- package/docs/adr/0163-legacy-display-name-resolution.md +1 -1
- package/docs/adr/0165-instances-hookless-by-default.md +1 -1
- package/docs/adr/0166-module-maintenance-and-deprecation-policy.md +3 -3
- package/docs/adr/0167-gate-trust-link-agpl-default.md +2 -2
- package/docs/adr/0167-module-catalog-source-vs-provenance.md +3 -3
- package/docs/adr/0169-bongos-serve-server-bring-up.md +1 -1
- package/docs/adr/0171-profile-rollup-join-and-consent.md +1 -1
- package/docs/adr/0172-editable-rank-roles-substrate-axis.md +2 -2
- package/docs/adr/0172-per-craft-compensation-ideator-credit-lane.md +4 -4
- package/docs/adr/0173-legacy-multi-ship-shortfall-not-backfilled.md +1 -1
- package/docs/adr/0174-government-terminology-ranks-not-roles.md +1 -1
- package/docs/adr/0177-goal-membership-kind.md +3 -3
- package/docs/adr/0178-the-copy-desk-flag-and-queue.md +1 -1
- package/docs/adr/0179-board-membership-predicate-grammar.md +1 -1
- package/docs/adr/0181-teardown-state-gate-and-address-retention.md +1 -1
- package/docs/adr/0182-project-visibility-two-axes.md +1 -1
- package/docs/adr/0183-criteria-close-themselves.md +1 -1
- package/docs/adr/0184-ship-requires-an-assurance.md +1 -1
- package/docs/adr/0185-spark-handoff-credit-split.md +1 -1
- package/docs/adr/0186-per-project-idea-templates.md +1 -1
- package/docs/adr/0187-collab-four-decisions.md +1 -1
- package/docs/adr/0187-oauth-handshake-cookie-lifetime.md +1 -1
- package/docs/adr/0188-patrol-runs-on-ci-not-the-server.md +2 -2
- package/docs/adr/0189-baseline-floors-and-the-freeze-detector.md +2 -2
- package/docs/adr/0191-majority-and-the-author-who-may-not-decide-alone.md +1 -1
- package/docs/adr/0192-a-category-orients-and-authorises-nothing.md +2 -2
- package/docs/adr/0193-pause-task-scoped-box-slices.md +1 -1
- package/docs/adr/0195-adr-numbers-are-checked-like-migration-numbers.md +2 -2
- package/docs/adr/0196-chrome-world-token-contract-and-the-landing-sheets.md +2 -2
- package/docs/adr/0197-the-ui-design-module.md +1 -1
- package/docs/adr/0198-third-party-skill-vendoring-policy.md +1 -1
- package/docs/adr/0203-doorway-changelog-out-of-module-api.md +2 -2
- package/docs/adr/0204-the-apex-is-dark-only.md +2 -2
- package/docs/adr/0205-federated-checkin-needs-the-hubs-own-signin-witness.md +1 -1
- package/docs/adr/0206-own-scoped-session-revocation-no-absolute-ceiling.md +1 -1
- package/docs/adr/0207-connections-implementation-departures-and-honest-limits.md +1 -1
- package/docs/adr/0208-application-lifecycle-the-handle-waits-and-the-vouch-has-no-minter.md +2 -2
- package/docs/adr/0209-one-budget-for-the-account-existence-oracle.md +1 -1
- package/docs/adr/0210-scouting-graduates-on-an-instance-asserted-owner-claim.md +1 -1
- package/docs/adr/0212-connections-on-the-profile-surface-and-addressing.md +1 -1
- package/docs/adr/0213-platform-terms-acceptance-is-the-hubs-own-witness.md +2 -2
- package/docs/adr/0215-the-recruiter-sliver-is-a-ceiling-not-a-step.md +6 -6
- package/docs/adr/0216-a-fake-pool-interpreter-must-fail-loudly-not-silently-ignore.md +2 -2
- package/docs/adr/0217-rank-gates-inviting-not-viewing.md +1 -1
- package/docs/adr/0218-the-apex-root-web-surface.md +2 -2
- package/docs/adr/0219-a-look-is-a-branding-pack-the-style-library.md +1 -1
- package/docs/adr/0220-an-in-house-rebuilt-skill-is-a-first-party-skill.md +1 -1
- package/docs/adr/0221-the-impeccable-method-is-one-skill-with-sub-command-playbooks.md +2 -2
- package/docs/adr/0222-the-image-family-under-the-hero-only-rule.md +2 -2
- package/docs/adr/0223-the-detector-is-two-tiers-in-the-kit.md +3 -3
- package/docs/adr/0224-module-skills-reach-the-core-checkout-as-untracked-self-ignored-copies.md +1 -1
- package/docs/adr/0225-privacy-suppresses-cross-project-surfaces-only.md +1 -1
- package/docs/adr/0226-one-stale-timer-reporting-degrades-enforcement-refuses.md +1 -1
- package/docs/adr/0227-a-task-network-map-is-refused-the-goal-graph-is-the-map.md +1 -1
- package/docs/adr/0230-a-look-skill-is-a-composition-grammar-the-palette-is-the-pack.md +1 -1
- package/docs/adr/0231-the-style-session-an-owner-authors-a-look-inside-the-contract.md +2 -2
- package/docs/adr/0232-rot-is-derived-not-swept-and-water-is-the-only-new-verb.md +2 -2
- package/docs/adr/0233-a-copy-proposal-is-a-task-carrying-a-patch.md +2 -2
- package/docs/adr/0234-idea-routing-capture-time-promotion-landing-matrix-homeless-inbox.md +2 -2
- package/docs/adr/0235-a-fix-category-is-kindbug-under-a-goal-no-column-required.md +11 -11
- package/docs/adr/0236-many-ideas-one-task-the-lineage-key-is-the-pair.md +5 -5
- package/docs/adr/0237-a-starter-bundle-is-a-preset-over-the-always-on-core-keyed-by-declared-type.md +5 -5
- package/docs/adr/0238-the-join-door-is-a-provisioning-settings-policy-key.md +1 -1
- package/docs/adr/0239-a-recommendation-is-a-table-that-carries-its-own-reason.md +4 -4
- package/docs/adr/0240-a-skipped-module-picker-stores-nothing-and-resolves-the-bundle-on-read.md +4 -4
- package/docs/adr/0241-the-artist-gate-is-a-per-project-deploy-gate-that-reads-a-state.md +1 -1
- package/docs/adr/0242-a-cascade-is-a-declaration-table-on-the-event-that-already-exists.md +2 -2
- package/docs/adr/0243-a-bundle-adjustment-belongs-to-the-bundle-not-the-advice-about-it.md +4 -4
- package/docs/adr/0244-a-catalog-search-is-a-view-over-the-rows-never-an-edit-to-the-selection.md +3 -3
- package/docs/adr/0245-the-way-back-into-an-optional-step-is-that-step-s-own-answer-route.md +7 -7
- package/docs/adr/0246-catalog-membership-is-a-projection-not-a-federation-side-effect.md +1 -1
- package/docs/adr/0247-the-join-door-is-one-composed-answer-and-dark-matter-has-no-live-verdict-yet.md +2 -2
- package/docs/adr/0248-a-hub-project-s-owner-is-the-provisioning-row-carried-on-a-port.md +3 -3
- package/docs/adr/0249-the-invite-step-is-the-done-panel-s-first-act-not-a-rail-step.md +3 -3
- package/docs/adr/0250-strict-versioning-the-version-boundary-is-the-scope-gate.md +6 -6
- package/docs/adr/0251-a-suggestion-of-who-to-invite-is-a-recruiting-surface-and-owes-the-opt-out.md +5 -5
- package/docs/adr/0252-the-self-hosted-visibility-report-is-a-pull-and-auto-appear-buys-a-retraction-lever.md +19 -19
- package/docs/adr/0253-the-takedown-lever-has-two-writers-and-provenance-is-a-column.md +2 -2
- package/docs/adr/0254-a-relayed-link-is-contained-downward-or-it-is-not-published.md +6 -6
- package/docs/adr/0255-a-public-lists-ordering-is-part-of-its-payload.md +2 -2
- package/docs/adr/0256-the-visibility-ceiling-is-the-sign-in-gate-too-and-the-reader-moves-to-the-composer.md +3 -3
- package/docs/adr/0257-auth-resolves-before-the-hall-mounts-anything.md +1 -1
- package/docs/adr/0258-the-public-cli-is-a-generated-client-package-not-the-published-core.md +1 -1
- package/docs/adr/0259-a-projects-departure-from-the-public-list-is-public.md +7 -7
- package/docs/adr/0260-the-application-is-the-consent-and-the-echo-is-the-gate.md +4 -4
- package/docs/adr/0261-a-preselect-always-carries-a-reason-the-bundle-summary-is-the-floor.md +1 -1
- package/docs/adr/0262-a-bug-never-lands-in-the-inbox.md +1 -1
- package/docs/adr/0263-how-a-version-closes.md +3 -3
- package/docs/adr/0264-the-ten-working-areas.md +3 -3
- package/docs/adr/0265-work-with-no-goal-and-the-order-the-cut-needs.md +5 -5
- package/docs/adr/0266-the-board-room-is-its-own-surface-reachable-by-whoever-may-vote.md +2 -2
- package/docs/adr/0267-unanimity-and-the-revise-and-re-sit-loop.md +1 -1
- package/docs/adr/0268-the-constitution-comes-from-two-roots.md +3 -3
- package/docs/adr/0269-the-cli-session-store-is-host-keyed-at-a-fixed-anchor.md +1 -1
- package/docs/adr/0270-rank-floor-derives-without-a-prediction.md +2 -2
- package/docs/adr/0271-the-ideator-surface-is-two-halves.md +3 -3
- package/docs/adr/0272-a-craft-is-an-identity-not-a-toolchain.md +4 -4
- package/docs/adr/0273-hall-nav-can-gate-on-a-permission.md +1 -1
- package/docs/adr/0274-one-kernel-three-role-packs.md +1 -1
- package/docs/adr/0275-one-source-for-a-written-role-responsibility.md +1 -1
- package/docs/adr/0276-the-skill-listing-budget-cannot-hold-every-trigger.md +1 -1
- package/docs/adr/0277-a-box-is-in-use-only-while-a-human-is-attached.md +1 -1
- package/docs/adr/0278-a-gated-project-still-takes-applications.md +2 -2
- package/docs/adr/0279-an-upgrade-is-proven-by-the-served-version-not-the-health-check.md +1 -1
- package/docs/adr/0280-the-unattended-lane-may-drive-a-co-tenant-because-the-roster-is-the-decision.md +1 -1
- package/docs/adr/0281-an-instance-identity-is-its-own-unix-account-and-pg-role.md +2 -2
- package/docs/adr/README.md +294 -294
- package/docs/api/openapi.json +72 -5
- package/docs/api-reference.md +8 -2
- package/docs/architecture.md +22 -22
- package/docs/branding-contract.md +5 -5
- package/docs/canonical-permissions.md +22 -22
- package/docs/copy-inventory.md +15 -13
- package/docs/copy-registry.json +35 -17
- package/docs/design/hall-direction-v2.md +3 -3
- package/docs/design/landing-page-direction-v2.md +1 -1
- package/docs/design/projects-hub-direction-v2.md +1 -1
- package/docs/file-map.md +3 -1
- package/docs/module-api-changelog.md +36 -1
- package/docs/modules-contract.md +25 -25
- package/docs/onboarding/browser-terminal-guide.md +1 -1
- package/docs/onboarding/diagrams/README.md +3 -3
- package/docs/onboarding/drachmae-and-karma.md +13 -13
- package/docs/onboarding/primer.md +7 -7
- package/docs/packs/artist.md +1 -1
- package/docs/packs/ideator.md +1 -1
- package/docs/project-context.template.md +3 -3
- package/docs/recipes/builder-box-lifecycle.md +5 -5
- package/docs/recipes/claude-design-loop.md +1 -1
- package/docs/recipes/core-release-pipeline.md +55 -14
- package/docs/recipes/figma-design-loop.md +1 -1
- package/docs/recipes/gds-db-backup.md +2 -2
- package/docs/recipes/instance-deploy.md +2 -2
- package/docs/recipes/instance-service-restart.md +3 -3
- package/docs/recipes/local-dev.md +2 -2
- package/docs/recipes/managed-settings-remote-control.md +3 -3
- package/docs/recipes/memory-backup.md +4 -4
- package/docs/recipes/memory-sync-conflicts.md +2 -2
- package/docs/recipes/multi-builder-merge.md +2 -2
- package/docs/recipes/ops-gotchas.md +4 -4
- package/docs/recipes/overnight-builder.md +1 -1
- package/docs/recipes/packaging-the-core.md +6 -6
- package/docs/recipes/private-npm-distribution.md +5 -5
- package/docs/recipes/search-index-ingestion.md +3 -3
- package/docs/recipes/self-host.md +5 -5
- package/docs/recipes/server-bring-up.md +1 -1
- package/docs/recipes/ship-and-regrade.md +2 -2
- package/docs/recipes/standalone-live-docs.md +1 -1
- package/docs/recipes/ui-look-before-you-ship.md +1 -1
- package/docs/recipes/upgrading-the-core.md +2 -2
- package/docs/recipes/work-on-a-task-from-your-dev-box.md +6 -6
- package/docs/research/cursor-competitive-analysis.md +3 -3
- package/docs/research/llm-model-agnostic-and-cheaper-grader.md +7 -7
- package/migrations/core_240_artist_gate_indexes.sql +48 -0
- package/migrations/core_240_goal_members_drop_legacy_role.sql +79 -0
- package/modules/dev-box/app/src/vendor/bongos-client.cjs +4 -0
- package/modules/hall-ui/public/watch.css +6 -0
- package/modules/hall-ui/public/watch.js +52 -6
- package/modules/lifecycle/cascade.js +37 -9
- package/modules/lifecycle/db-claims.js +5 -2
- package/modules/lifecycle/db-goals.js +4 -3
- package/modules/lifecycle/db-overrides.js +117 -4
- package/modules/lifecycle/db-tasks.js +63 -0
- package/modules/lifecycle/migrations/lifecycle_001_goal_first_leads.sql +12 -4
- package/modules/lifecycle/module.json +2 -1
- package/modules/lifecycle/pg-constraint-fail.js +49 -0
- package/modules/lifecycle/routes/artist-gate.js +101 -0
- package/modules/lifecycle/routes/claims.js +13 -1
- package/modules/lifecycle/routes/lifecycle.js +6 -0
- package/modules/lifecycle/routes/task-write-routes.js +7 -0
- package/modules/lifecycle/routes/tasks.js +24 -0
- package/modules/lifecycle/task-classifier.js +10 -1
- package/modules/lifecycle/tests/cascade.mjs +43 -0
- package/modules/provisioning/provisioning.js +79 -3
- package/modules/provisioning/routes/provisioning.js +6 -1
- package/modules/provisioning/tests/provisioning.mjs +8 -8
- package/modules/security/secret-scrub.js +40 -4
- package/modules/status-ui/public/README.md +1 -1
- package/modules/ui-design/docs/design-contract.md +2 -2
- package/modules/ui-design/kit/README.md +1 -1
- package/modules/ui-design/kit/serve.js +1 -0
- package/modules/ui-design/skills/README.md +6 -6
- package/modules/ui-design/skills/brandkit/SKILL.md +1 -1
- package/modules/ui-design/skills/design-taste-frontend/SKILL.md +1 -1
- package/modules/ui-design/skills/design-taste-frontend-v1/SKILL.md +1 -1
- package/modules/ui-design/skills/gpt-taste/SKILL.md +1 -1
- package/modules/ui-design/skills/high-end-visual-design/SKILL.md +1 -1
- package/modules/ui-design/skills/image-to-code/SKILL.md +1 -1
- package/modules/ui-design/skills/imagegen-frontend-mobile/SKILL.md +1 -1
- package/modules/ui-design/skills/imagegen-frontend-web/SKILL.md +1 -1
- package/modules/ui-design/skills/impeccable/SKILL.md +1 -1
- package/modules/ui-design/skills/industrial-brutalist-ui/SKILL.md +1 -1
- package/modules/ui-design/skills/minimalist-ui/SKILL.md +1 -1
- package/modules/ui-design/skills/redesign-existing-projects/SKILL.md +1 -1
- package/modules/ui-design/skills/stitch-design-taste/SKILL.md +1 -1
- package/modules/ui-design/skills/style/SKILL.md +2 -2
- package/modules/ui-design/styles/README.md +3 -3
- package/modules/ui-design/styles/blueprint/DESIGN.md +1 -1
- package/modules/ui-design/styles/chrome-world/DESIGN.md +1 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/audit-rank-roles.js +172 -0
- package/scripts/gds/backfill-task-rewards.js +9 -4
- package/scripts/gds/build-cli-package.js +1 -0
- package/scripts/gds/claim.js +94 -9
- package/scripts/gds/fitness.js +8 -8
- package/scripts/gds/go-live.js +139 -5
- package/scripts/gds/land-watch.js +13 -5
- package/scripts/gds/mirror-redact.js +13 -2
- package/scripts/gds/package-core.js +11 -3
- package/scripts/gds/release.js +55 -0
- package/scripts/gds/ship-land.js +10 -2
- package/scripts/gds/ship-regen.js +41 -8
- package/scripts/gds/start.js +7 -4
- package/scripts/gds/worktree-claim-guard.js +27 -1
- package/scripts/public-mirror-export.js +17 -4
- package/src/bongos/api-errors.js +9 -0
- package/src/bongos/artist-gate.js +204 -0
- package/src/branding.js +15 -0
- package/src/module-api.js +34 -1
- package/tests/api_path_404.mjs +28 -0
- package/tests/artist_gate.mjs +234 -0
- package/tests/artist_gate_release.mjs +283 -0
- package/tests/artist_gate_route.mjs +174 -0
- package/tests/box_scope_predicate.mjs +117 -0
- package/tests/claim_error_surface.mjs +163 -1
- package/tests/cli_exit_no_abort.mjs +256 -3
- package/tests/credit_log_single_writer.mjs +94 -0
- package/tests/currency_label.mjs +11 -4
- package/tests/go_live.mjs +144 -0
- package/tests/helpers.mjs +8 -0
- package/tests/main_worktree_busy_reason.mjs +167 -0
- package/tests/membership_kind_lockstep.mjs +88 -0
- package/tests/mirror_redact.mjs +14 -0
- package/tests/module_api.mjs +6 -0
- package/tests/provision_settings_apply.mjs +13 -5
- package/tests/provisioning_settings.mjs +11 -7
- package/tests/provisioning_settings_apply.mjs +4 -4
- package/tests/provisioning_settings_env.mjs +59 -7
- package/tests/public_mirror_export.mjs +12 -0
- package/tests/rank_roles_audit.mjs +114 -0
- package/tests/scrubber_corpus.mjs +70 -2
- package/tests/start_rebase_warning.mjs +50 -0
- package/tests/task_field_bounds_match_db.mjs +140 -0
- package/tests/watch_roster_self_row.mjs +289 -0
|
@@ -5,7 +5,7 @@ A **generated**, zero-dependency typed client for the Bongos API — produced fr
|
|
|
5
5
|
by hand; it regenerates when the spec changes, so it can never drift from the routes.
|
|
6
6
|
|
|
7
7
|
- API version: **v1** (served at `/api/bongos/v1`)
|
|
8
|
-
-
|
|
8
|
+
- 373 operations across 58 resource groups
|
|
9
9
|
|
|
10
10
|
## Use it from your project
|
|
11
11
|
|
|
@@ -126,6 +126,10 @@ function createClient(opts = {}) {
|
|
|
126
126
|
// GET /analytics/builder/{id} — rank: any-builder — GET /analytics/builder/:id
|
|
127
127
|
getAnalyticsBuilderId: (args) => request("GET", "/analytics/builder/{id}", { hasBody: false }, args),
|
|
128
128
|
},
|
|
129
|
+
"artistGate": {
|
|
130
|
+
// GET /artist-gate — rank: any-builder — GET /artist-gate
|
|
131
|
+
getArtistGate: (args) => request("GET", "/artist-gate", { hasBody: false }, args),
|
|
132
|
+
},
|
|
129
133
|
"auditLog": {
|
|
130
134
|
// GET /audit-log — rank: metic+archon — GET /audit-log
|
|
131
135
|
getAuditLog: (args) => request("GET", "/audit-log", { hasBody: false }, args),
|
|
@@ -125,6 +125,10 @@ function createClient(opts = {}) {
|
|
|
125
125
|
// GET /analytics/builder/{id} — rank: any-builder — GET /analytics/builder/:id
|
|
126
126
|
getAnalyticsBuilderId: (args) => request("GET", "/analytics/builder/{id}", { hasBody: false }, args),
|
|
127
127
|
},
|
|
128
|
+
"artistGate": {
|
|
129
|
+
// GET /artist-gate — rank: any-builder — GET /artist-gate
|
|
130
|
+
getArtistGate: (args) => request("GET", "/artist-gate", { hasBody: false }, args),
|
|
131
|
+
},
|
|
128
132
|
"auditLog": {
|
|
129
133
|
// GET /audit-log — rank: metic+archon — GET /audit-log
|
|
130
134
|
getAuditLog: (args) => request("GET", "/audit-log", { hasBody: false }, args),
|
|
@@ -23,6 +23,7 @@ export interface GetAchievementsResponse { achievements: unknown }
|
|
|
23
23
|
export interface GetAgentRunsIdResponse { ok: boolean; run: unknown }
|
|
24
24
|
export interface GetAgentsNameResponse { ok: boolean; agent: unknown }
|
|
25
25
|
export interface GetAgentsResponse { ok: boolean; agents: unknown; counts: unknown; vocabulary: unknown }
|
|
26
|
+
export interface GetArtistGateResponse { ok: boolean; mode: unknown; since: unknown; holds: boolean; truncated: unknown; reviews: unknown; halt: unknown }
|
|
26
27
|
export interface GetAuditLogResponse { rows: unknown; page: unknown }
|
|
27
28
|
export interface GetAuthAppPairInfoResponse { pair_code: unknown; device_name: unknown; platform: unknown; status: unknown }
|
|
28
29
|
export interface GetAuthWebAdmissionStatusResponse { admitted: boolean }
|
|
@@ -470,6 +471,10 @@ export interface BongosClient {
|
|
|
470
471
|
/** GET /analytics/builder/{id} — rank: any-builder */
|
|
471
472
|
getAnalyticsBuilderId(args?: RequestArgs): Promise<ApiResponse>;
|
|
472
473
|
};
|
|
474
|
+
"artistGate": {
|
|
475
|
+
/** GET /artist-gate — rank: any-builder */
|
|
476
|
+
getArtistGate(args?: RequestArgs): Promise<GetArtistGateResponse>;
|
|
477
|
+
};
|
|
473
478
|
"auditLog": {
|
|
474
479
|
/** GET /audit-log — rank: metic+archon */
|
|
475
480
|
getAuditLog(args?: RequestArgs): Promise<GetAuditLogResponse>;
|
|
@@ -122,6 +122,10 @@ export function createClient(opts = {}) {
|
|
|
122
122
|
// GET /analytics/builder/{id} — rank: any-builder — GET /analytics/builder/:id
|
|
123
123
|
getAnalyticsBuilderId: (args) => request("GET", "/analytics/builder/{id}", { hasBody: false }, args),
|
|
124
124
|
},
|
|
125
|
+
"artistGate": {
|
|
126
|
+
// GET /artist-gate — rank: any-builder — GET /artist-gate
|
|
127
|
+
getArtistGate: (args) => request("GET", "/artist-gate", { hasBody: false }, args),
|
|
128
|
+
},
|
|
125
129
|
"auditLog": {
|
|
126
130
|
// GET /audit-log — rank: metic+archon — GET /audit-log
|
|
127
131
|
getAuditLog: (args) => request("GET", "/audit-log", { hasBody: false }, args),
|
|
@@ -27,11 +27,13 @@
|
|
|
27
27
|
"idp": false
|
|
28
28
|
},
|
|
29
29
|
"project": {
|
|
30
|
-
"_note": "Per-project policy the PLATFORM decides and this instance OBEYS (task 1003139, goal 1000058). Stored on the platform's provisioning_instances.settings; written here as <PREFIX>_PLATFORM_VISIBILITY / <PREFIX>_JOINABILITY / <PREFIX>_VISIBILITY by the provisioning runner, which re-writes web.env and restarts the service when the owner changes one. The defaults are TODAY's behavior, so an instance that never receives a push — a self-hosted one, or one provisioned before this channel — keeps behaving exactly as it does now. platformVisibility (who may READ this instance's own pages): public | gated. joinability (HOW someone becomes a member): open | apply | invite_only. visibility (the join door, ADR 0182 D1 — how this project stands on the platform's map): public | private | stealth; it does NOT decide whether the project is on the map, publishability does. joinGrant (what a PUBLIC join GRANTS): view | apply | full — the ceiling joinability may only narrow (ADR 0182 D6 / ADR 0245); `full` narrows nothing, which is why it is the default.",
|
|
30
|
+
"_note": "Per-project policy the PLATFORM decides and this instance OBEYS (task 1003139, goal 1000058). Stored on the platform's provisioning_instances.settings; written here as <PREFIX>_PLATFORM_VISIBILITY / <PREFIX>_JOINABILITY / <PREFIX>_VISIBILITY by the provisioning runner, which re-writes web.env and restarts the service when the owner changes one. The defaults are TODAY's behavior, so an instance that never receives a push — a self-hosted one, or one provisioned before this channel — keeps behaving exactly as it does now. platformVisibility (who may READ this instance's own pages): public | gated. joinability (HOW someone becomes a member): open | apply | invite_only. visibility (the join door, ADR 0182 D1 — how this project stands on the platform's map): public | private | stealth; it does NOT decide whether the project is on the map, publishability does. joinGrant (what a PUBLIC join GRANTS): view | apply | full — the ceiling joinability may only narrow (ADR 0182 D6 / ADR 0245); `full` narrows nothing, which is why it is the default. artistGate (ADR 0241 — how hard this project's artist reviews bite): off | advisory | strict, written as <PREFIX>_ARTIST_GATE. off files no artist review tasks at all; advisory files them and blocks nothing; strict files them and lets an unresolved one hold the DEPLOY — this instance's core pin may not move while one is open. It never holds a builder's ship, which is what keeps it compatible with ADR 0162. It is the one key here whose default is NOT today's behaviour: `strict` is the owner's ruling (ADR 0241 §4), safe as a default because the worst case is a pin that waits, never a stranded builder, and the project owner holds the release valve. artistGateSince (<PREFIX>_ARTIST_GATE_SINCE) is its companion stamp — the moment the gate was last RAISED to strict, so the hold is not retroactive (ADR 0241 §5); empty means no cutoff, which is the right answer for a project that has been strict since it stood up.",
|
|
31
31
|
"platformVisibility": "public",
|
|
32
32
|
"joinability": "apply",
|
|
33
33
|
"visibility": "public",
|
|
34
|
-
"joinGrant": "full"
|
|
34
|
+
"joinGrant": "full",
|
|
35
|
+
"artistGate": "strict",
|
|
36
|
+
"artistGateSince": ""
|
|
35
37
|
},
|
|
36
38
|
"repo": {
|
|
37
39
|
"owner": "",
|
|
@@ -19,8 +19,8 @@ We needed an architecture that:
|
|
|
19
19
|
|
|
20
20
|
We will run the entire V1 stack on a **single VPS** with the following components:
|
|
21
21
|
|
|
22
|
-
- **Hosting:** DigitalOcean droplet, Ubuntu 24.04 LTS (see [0002](
|
|
23
|
-
- **Reverse proxy / TLS:** Caddy (originally for Let's Encrypt; superseded by [0003](
|
|
22
|
+
- **Hosting:** DigitalOcean droplet, Ubuntu 24.04 LTS (see [0002](./0002-digitalocean-over-hetzner.md))
|
|
23
|
+
- **Reverse proxy / TLS:** Caddy (originally for Let's Encrypt; superseded by [0003](./0003-cloudflare-origin-cert-over-letsencrypt.md))
|
|
24
24
|
- **Runtime:** Node.js 22 LTS
|
|
25
25
|
- **Database:** PostgreSQL 16 (system package)
|
|
26
26
|
- **Game server:** Colyseus 0.16 — open-source authoritative-server framework over WebSockets
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## Context
|
|
8
8
|
|
|
9
|
-
After locking in the [single-VPS stack](
|
|
9
|
+
After locking in the [single-VPS stack](./0001-stack-choice-single-vps.md), we needed a hosting provider. Hetzner was the initial pick on cost (~$5/mo for an equivalent VPS). Setup was blocked at Hetzner's KYC step, which requires identity verification documents and a turnaround period before the account is provisioned.
|
|
10
10
|
|
|
11
11
|
## Decision
|
|
12
12
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 0008 — Google Chat integration auth model: OAuth as the operator user
|
|
2
2
|
|
|
3
|
-
- **Status:** Superseded by [ADR 0032](0032-discord-mirror-of-gds.md) (outbound) and [ADR 0033](
|
|
3
|
+
- **Status:** Superseded by [ADR 0032](0032-discord-mirror-of-gds.md) (outbound) and [ADR 0033](0033-discord-bot-service-principal.md) (bot/inbound) — Google Chat fully retired 2026-06-05, replaced by Discord
|
|
4
4
|
- **Date:** 2026-05-09
|
|
5
5
|
- **Deciders:** Lars
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
V1 needs to render coherent terrain boundaries: grass islands within sand, sand
|
|
10
10
|
beaches against shallow sea, marble flagstone paths through grass, cliffs.
|
|
11
|
-
Earlier work in [ADR 0008](
|
|
11
|
+
Earlier work in [ADR 0008](./0008-family-based-tile-generation.md) established
|
|
12
12
|
the family pipeline and produced beautiful single illustrations for continuous
|
|
13
13
|
objects (containers, houses), but that pipeline could not produce a true
|
|
14
14
|
autotile family — a set of tiles where every cell is a different topology
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# 0011 — Terrain-id world map + dispatched render strategies (Phase D)
|
|
2
2
|
|
|
3
|
-
- **Status:** Accepted; cell data model extended by [ADR 0012](
|
|
3
|
+
- **Status:** Accepted; cell data model extended by [ADR 0012](./0012-ground-object-cell-split.md)
|
|
4
4
|
- **Date:** 2026-05-09
|
|
5
5
|
- **Deciders:** Lars
|
|
6
6
|
|
|
7
|
-
> **Update (same day):** [ADR 0012](
|
|
7
|
+
> **Update (same day):** [ADR 0012](./0012-ground-object-cell-split.md)
|
|
8
8
|
> splits the cell from one terrain id into two layers — ground (always
|
|
9
9
|
> defined) + object (optional overlay). The dispatched render
|
|
10
10
|
> strategies (`single` / `blob47` / `path16`) and the autotile cross-
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
## Context
|
|
15
15
|
|
|
16
|
-
[ADR 0008](
|
|
16
|
+
[ADR 0008](./0008-family-based-tile-generation.md) and
|
|
17
17
|
[ADR 0009](./0009-autotile-architecture.md) established two new asset
|
|
18
18
|
pipelines (family + autotile) but stopped at the asset boundary. The
|
|
19
19
|
runtime renderer still treated the world as a flat 2D grid of tile-id
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
- **Status:** Accepted
|
|
4
4
|
- **Date:** 2026-05-10
|
|
5
5
|
- **Deciders:** Lars
|
|
6
|
-
- **Extends:** [ADR 0012](
|
|
6
|
+
- **Extends:** [ADR 0012](./0012-ground-object-cell-split.md) (cell model), [ADR 0011](./0011-terrain-id-rendering-model.md) (render dispatch), [ADR 0009](./0009-autotile-architecture.md) (autotile families)
|
|
7
7
|
|
|
8
8
|
## Context
|
|
9
9
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- **Date:** 2026-05-11
|
|
5
5
|
- **Deciders:** Lars
|
|
6
6
|
- **Track:** `internal` (art pipeline)
|
|
7
|
-
- **Extends:** [ADR 0008-a](
|
|
7
|
+
- **Extends:** [ADR 0008-a](./0008-family-based-tile-generation.md) (family-based tile generation), [ADR 0009](./0009-autotile-architecture.md) (autotile architecture)
|
|
8
8
|
|
|
9
9
|
## Context
|
|
10
10
|
|
|
@@ -122,4 +122,4 @@ Rejected because that's the system that was failing Lars in the first place. Man
|
|
|
122
122
|
**Operationally:**
|
|
123
123
|
- `/builder-start` filters by `status='ready'`, so a builder never sees a dep-blocked task in their menu. Good UX.
|
|
124
124
|
- `/builder-claim` returns `DEPS_NOT_SHIPPED` if a manually-promoted task is claimed before its deps land. CLI prints the blockers. Good UX.
|
|
125
|
-
- The `[ADR 0014](../adr
|
|
125
|
+
- The `[ADR 0014](../adr/0014-families-canonical-over-vocabulary.md)` ADR number was taken by the families work; this one is **0015**.
|
|
@@ -125,7 +125,7 @@ Tokens stay authority-free. `builder_sessions` issuance is unchanged by the rank
|
|
|
125
125
|
**Costs:**
|
|
126
126
|
- Every privileged route must remember to call `requireRank`. A forgotten check is a silent hole — mitigated by the auditor task ([#266](https://example.com/builders#/task/266)/V3.R44) which fails loudly when a privileged route lacks a rank gate.
|
|
127
127
|
- Rank read on every privileged request (one extra column on an existing join). Accepted.
|
|
128
|
-
- The two-rank V3 scope (Archon + Thetes) is deliberately minimal; the full ladder in [#106](https://example.com/builders#/task/106)'s enum is reserved but unimplemented, so promoting anyone to a middle rank is a no-op until those ranks gain route grants. Documented, not a bug. **(Superseded by [ADR 0018](
|
|
128
|
+
- The two-rank V3 scope (Archon + Thetes) is deliberately minimal; the full ladder in [#106](https://example.com/builders#/task/106)'s enum is reserved but unimplemented, so promoting anyone to a middle rank is a no-op until those ranks gain route grants. Documented, not a bug. **(Superseded by [ADR 0018](0018-three-rank-model-goes-live.md), task [#360](https://example.com/builders#/task/360): the three-rank `xenos`/`metic`/`archon` model went live — `xenos` is now the default entry rank and `metic` the approved working rank, both wired with route grants. The trust-boundary mechanism in this ADR is unchanged; only the set of live ranks widened.)**
|
|
129
129
|
|
|
130
130
|
**Operationally:**
|
|
131
131
|
- When adding any new write/privileged route, the default is `requireRank('archon')` until a lower rank is explicitly granted — fail closed, not open.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Date:** 2026-05-27
|
|
4
4
|
**Context:** Task [#360](https://example.com/builders#/task/360), follow-up to the V3.R86 ([#305](https://example.com/builders#/task/305)) CLAUDE.md audit. Advances GDS-V3 criterion
|
|
5
|
-
C2 (`three-ranks-gate-everything`). Builds on (and partially supersedes) [ADR 0016](
|
|
5
|
+
C2 (`three-ranks-gate-everything`). Builds on (and partially supersedes) [ADR 0016](0016-trust-boundary-server-enforced-permissions.md).
|
|
6
6
|
**Status:** Accepted.
|
|
7
7
|
|
|
8
8
|
## Problem
|
|
@@ -47,7 +47,7 @@ change, not an enum migration.
|
|
|
47
47
|
| Create / promote / edit tasks, deps, confirm, done-when scope | ❌ | ❌ | ✅ |
|
|
48
48
|
| Grant/revoke rank, offboard, version close, infra | ❌ | ❌ | ✅ |
|
|
49
49
|
|
|
50
|
-
> **Update (2026-06-26, [ADR 0090](
|
|
50
|
+
> **Update (2026-06-26, [ADR 0090](0090-metic-task-authoring.md)):** the *"Create / promote / edit tasks, deps"* part of row 7 moved to **✅ for Metic** — a Metic may now author + shape tasks (`POST /tasks`, `PATCH /tasks/:id`, `POST /tasks/:id/promote`, and the `tasks/:id/{dependencies,criteria}` CRUD). `confirm` (grader-bypass), `done-when` *scope*-setting, abandon, rank, and version-close stay Archon-only (row 8 is unchanged). The table above is preserved as the 2026 record; ADR 0090 is the current authority.
|
|
51
51
|
|
|
52
52
|
### Mechanisms
|
|
53
53
|
|
|
@@ -92,6 +92,6 @@ they reference real.
|
|
|
92
92
|
## Supersedes
|
|
93
93
|
|
|
94
94
|
The "two-rank V3 scope (Archon + Thetes) is deliberately minimal" bullet in
|
|
95
|
-
[ADR 0016 §Consequences](
|
|
95
|
+
[ADR 0016 §Consequences](0016-trust-boundary-server-enforced-permissions.md#consequences) is
|
|
96
96
|
superseded: the middle/entry ranks are no longer all reserved-and-unwired — `metic` and `xenos` are
|
|
97
97
|
live as of this ADR.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ADR 0020 — Security model — public stub (full ADR is server-side)
|
|
2
2
|
|
|
3
3
|
**Date:** 2026-05-28
|
|
4
|
-
**Context:** Task [#287](https://example.com/builders#/task/287) (V3.R68), GDS-V3 criterion C9. Companion to [ADR 0019](
|
|
4
|
+
**Context:** Task [#287](https://example.com/builders#/task/287) (V3.R68), GDS-V3 criterion C9. Companion to [ADR 0019](0019-red-team-bounty-payout-table.md) (bounty table), [ADR 0018](0018-three-rank-model-goes-live.md) (rank model), [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) (server-enforced trust boundary).
|
|
5
5
|
**Status:** Accepted.
|
|
6
6
|
|
|
7
7
|
## Problem
|
|
@@ -10,7 +10,7 @@ A security ADR worth writing is a security ADR worth attacking. The threat model
|
|
|
10
10
|
|
|
11
11
|
But we *also* need this document to exist and be readable by trusted builders (Archon, Metic) — otherwise the system has no shared model of how it defends itself, and every new privileged route ends up reinventing the threat-list ad hoc. The red-team bounty (criterion C9) only makes sense if Metics know roughly where the surface is.
|
|
12
12
|
|
|
13
|
-
We've already adopted [ADR 0016](
|
|
13
|
+
We've already adopted [ADR 0016](0016-trust-boundary-server-enforced-permissions.md): authority lives on the server, not in the repo. The same logic applies to the security ADR itself — its content should live where its enforcement does.
|
|
14
14
|
|
|
15
15
|
## Decision
|
|
16
16
|
|
|
@@ -30,21 +30,21 @@ The **full security ADR is server-side**, served by a Metic+-gated endpoint and
|
|
|
30
30
|
|
|
31
31
|
The full ADR is structured as:
|
|
32
32
|
|
|
33
|
-
1. **Trust boundary mechanics** — the actual implementation of [ADR 0016](
|
|
33
|
+
1. **Trust boundary mechanics** — the actual implementation of [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) per route: which routes are gated, by what rank, where the rank read lives in the request lifecycle, and what fails closed.
|
|
34
34
|
2. **Threat model** — the set of attackers we model (sandboxed builder, malicious Metic, leaked GitHub OAuth, supply-chain compromise, lost laptop) and what each can and cannot do under the current design.
|
|
35
35
|
3. **Defense-in-depth inventory** — per privileged surface, the specific layers in front of it (rank check + audit log + rate limit + input validation + content TTL + …) and why each layer was chosen. This is the section that would most directly aid an attacker.
|
|
36
36
|
4. **Known weaknesses** — the specific places where a defense is thinner than we'd like, with the reasons we haven't fixed them yet (deferred to a later version, cost/benefit, etc.). Highest sensitivity.
|
|
37
|
-
5. **Red-team bounty alignment** — how a confirmed vulnerability_report maps onto the table in [ADR 0019](
|
|
37
|
+
5. **Red-team bounty alignment** — how a confirmed vulnerability_report maps onto the table in [ADR 0019](0019-red-team-bounty-payout-table.md), where the auto-confirmation path lives (R67/R68), and which surfaces are explicit invitations vs. out-of-scope (e.g. droplet-host vulns vs. application vulns).
|
|
38
38
|
|
|
39
39
|
Each section is updated when the underlying mechanism changes. The full ADR is the *living* document; this stub is the *pointer*.
|
|
40
40
|
|
|
41
41
|
### Why not just chmod the repo file?
|
|
42
42
|
|
|
43
|
-
The Example repo is on GitHub. Marking a single file private is awkward (git history exposes it; collaborators see everything). The cleanest available primitive is "the file is on the droplet, the server reads it, the API gates access." That collapses to the same trust boundary [ADR 0016](
|
|
43
|
+
The Example repo is on GitHub. Marking a single file private is awkward (git history exposes it; collaborators see everything). The cleanest available primitive is "the file is on the droplet, the server reads it, the API gates access." That collapses to the same trust boundary [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) already enforces for everything else.
|
|
44
44
|
|
|
45
45
|
### This is not security-through-obscurity
|
|
46
46
|
|
|
47
|
-
The defense doesn't depend on the ADR's secrecy. Every protection mentioned in the full ADR is independently enforced in code (rank middleware, audit log, input validation, etc.). Withholding the document raises the cost of an attacker's reconnaissance — it doesn't *create* the defense. The bounty table ([ADR 0019](
|
|
47
|
+
The defense doesn't depend on the ADR's secrecy. Every protection mentioned in the full ADR is independently enforced in code (rank middleware, audit log, input validation, etc.). Withholding the document raises the cost of an attacker's reconnaissance — it doesn't *create* the defense. The bounty table ([ADR 0019](0019-red-team-bounty-payout-table.md)) names the gain for the attacker who reverse-engineers it anyway: a high-severity finding pays out 1000 example. The system *wants* serious red-teamers; what it doesn't want is to hand them the map for free.
|
|
48
48
|
|
|
49
49
|
## Alternatives considered
|
|
50
50
|
|
|
@@ -63,8 +63,8 @@ The defense doesn't depend on the ADR's secrecy. Every protection mentioned in t
|
|
|
63
63
|
|
|
64
64
|
## Cross-references
|
|
65
65
|
|
|
66
|
-
- [ADR 0016](
|
|
67
|
-
- [ADR 0018](
|
|
68
|
-
- [ADR 0019](
|
|
66
|
+
- [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) — the server-enforced trust boundary the security model rests on.
|
|
67
|
+
- [ADR 0018](0018-three-rank-model-goes-live.md) — the three-rank model whose gates the security ADR documents.
|
|
68
|
+
- [ADR 0019](0019-red-team-bounty-payout-table.md) — the payout table a confirmed vulnerability_report maps onto.
|
|
69
69
|
- Migration [<redacted>.sql](../../migrations/<redacted>.sql) — the report intake table (R63).
|
|
70
70
|
- Migration [033_audit_log.sql](../../migrations/033_audit_log.sql) — the audit ledger every privileged write lands in (R35).
|
|
@@ -92,8 +92,8 @@ If V4 retires per-skill defaults in favor of per-skill-*kind* defaults (the broa
|
|
|
92
92
|
|
|
93
93
|
## Cross-references
|
|
94
94
|
|
|
95
|
-
- [Migration 037](../../migrations
|
|
95
|
+
- [Migration 037](../../migrations/037_builder_skill_model_prefs.sql) — the schema change.
|
|
96
96
|
- [`src/bongos/skill-prefs.js`](../../src/bongos/skill-prefs.js) — the helper module and source of truth for defaults.
|
|
97
97
|
- [`tests/skill_prefs.mjs`](../../tests/skill_prefs.mjs) — unit coverage for the pure helpers.
|
|
98
|
-
- [ADR 0017](
|
|
98
|
+
- [ADR 0017](0017-code-simplification-and-repo-cleanliness.md) — same spirit: keep judgment work intentional, mechanism work cheap.
|
|
99
99
|
- CLAUDE.md §2 — the project-wide subagent routing policy this ADR sits beside (not replaces — the policy is the default the matrix opens with).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ADR 0022 — Secrets policy
|
|
2
2
|
|
|
3
3
|
**Date:** 2026-05-28
|
|
4
|
-
**Context:** Task [#279](https://example.com/builders#/task/279) (V3.R60), GDS-V3 criterion C8. Originally built on a pre-commit hook + CI scan (task [#257](https://example.com/builders#/task/257), V3.R36); those surfaces were lost in the core extraction and rebuilt as the prevent/gate/patrol layers under goal 1000076 (task 1003131). Pairs with [ADR 0020](
|
|
4
|
+
**Context:** Task [#279](https://example.com/builders#/task/279) (V3.R60), GDS-V3 criterion C8. Originally built on a pre-commit hook + CI scan (task [#257](https://example.com/builders#/task/257), V3.R36); those surfaces were lost in the core extraction and rebuilt as the prevent/gate/patrol layers under goal 1000076 (task 1003131). Pairs with [ADR 0020](0020-security-model-public-stub.md) (security model — public stub) and [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) (trust boundary).
|
|
5
5
|
**Enforcement rebuilt:** 2026-08-19 (task 1003131, goal 1000076) — see the Problem section's box.
|
|
6
6
|
**Status:** Accepted.
|
|
7
7
|
|
|
@@ -46,7 +46,7 @@ A "secret" for the purposes of this policy is any string that, if disclosed, wou
|
|
|
46
46
|
- Stripe live + test secret keys (`sk_live_`, `sk_test_`)
|
|
47
47
|
- Any RSA / EC / DSA / Ed25519 private key (`-----BEGIN … PRIVATE KEY-----`)
|
|
48
48
|
- TLS private keys (`-----BEGIN PRIVATE KEY-----`)
|
|
49
|
-
- Cloudflare Origin Certificate private halves (lives on droplet only — see [ADR 0003](
|
|
49
|
+
- Cloudflare Origin Certificate private halves (lives on droplet only — see [ADR 0003](0003-cloudflare-origin-cert-over-letsencrypt.md))
|
|
50
50
|
- Postgres passwords (if peer-auth ever gets replaced with password auth — see [`docs/recipes/ops-gotchas.md`](../recipes/ops-gotchas.md) for the current peer-auth setup)
|
|
51
51
|
- GDS session bearer tokens (any value of `gds_session` / `pms_session`)
|
|
52
52
|
|
|
@@ -67,7 +67,7 @@ Three lanes, each with explicit access controls. **Nothing else** is sanctioned;
|
|
|
67
67
|
| Droplet rotating | `/etc/example/secrets/<name>` (chmod 600, per-secret file) | no | only the `lars` user + root | individual services that read one file at startup |
|
|
68
68
|
| Builder laptop | `~/.config/otb/env` AND `.env.local` (gitignored, lives at the repo root in the main checkout and copies into worktrees on session start) | no — explicitly gitignored | the builder's macOS user account | `art/pipeline/gen_api.py` reads `~/.config/otb/env`; everything else reads `.env.local` |
|
|
69
69
|
|
|
70
|
-
> **Multi-line secrets (e.g. a GitHub App private key, PEM).** Store in the droplet long-lived lane as a single line with literal `\n` escapes — `GITHUB_APP_PRIVATE_KEY="<redacted>"` — and the reader restores the newlines (`src/bongos/github-push.js normalizePem`). The GitHub App credential for server-mediated publish (`GITHUB_APP_ID` + `GITHUB_APP_INSTALLATION_ID` + `GITHUB_APP_PRIVATE_KEY`, [ADR 0055](
|
|
70
|
+
> **Multi-line secrets (e.g. a GitHub App private key, PEM).** Store in the droplet long-lived lane as a single line with literal `\n` escapes — `GITHUB_APP_PRIVATE_KEY="<redacted>"` — and the reader restores the newlines (`src/bongos/github-push.js normalizePem`). The GitHub App credential for server-mediated publish (`GITHUB_APP_ID` + `GITHUB_APP_INSTALLATION_ID` + `GITHUB_APP_PRIVATE_KEY`, [ADR 0055](0055-server-mediated-branch-publish.md) / task 1028) lives here alongside the `GITHUB_PUSH_TOKEN` PAT it replaces.
|
|
71
71
|
|
|
72
72
|
Notably **not allowed**:
|
|
73
73
|
|
|
@@ -86,7 +86,7 @@ When a credential is rotated — either because we found a leak or because the c
|
|
|
86
86
|
4. **Revoke the old credential** at the issuing service. Do this AFTER step 2; the brief overlap is intentional so a slow-rolling service catches both keys.
|
|
87
87
|
5. **Log the rotation** — a one-line entry to [`docs/recipes/ops-gotchas.md`](../recipes/ops-gotchas.md) (date + which credential + why), so the next builder spinning up knows what changed when.
|
|
88
88
|
|
|
89
|
-
GDS session tokens rotate automatically — they're 30-day-TTL, refresh-on-use, revocable per session or per builder (migration `<redacted>.sql`, ADR-aligned with [ADR 0016](
|
|
89
|
+
GDS session tokens rotate automatically — they're 30-day-TTL, refresh-on-use, revocable per session or per builder (migration `<redacted>.sql`, ADR-aligned with [ADR 0016](0016-trust-boundary-server-enforced-permissions.md)). No manual rotation needed for those except in a leak scenario, which falls under "What to do on a hit" below.
|
|
90
90
|
|
|
91
91
|
## What to do when the scan finds a hit
|
|
92
92
|
|
|
@@ -109,7 +109,7 @@ If a future audit *does* find a hit, follow "What to do when the scan finds a hi
|
|
|
109
109
|
|
|
110
110
|
## Scrubbing secrets OUT of session uploads (the BFG corpus)
|
|
111
111
|
|
|
112
|
-
The enforcement above keeps secrets out of the **repo**. A second egress exists: the BFG session-inefficiency evaluator ([ADR 0027](
|
|
112
|
+
The enforcement above keeps secrets out of the **repo**. A second egress exists: the BFG session-inefficiency evaluator ([ADR 0027](0027-bfg-session-inefficiency-evaluator.md)) uploads a digest of each Claude Code session to the GDS `sessions` corpus. A transcript contains every file read, command output, and pasted value — so the upload path is scrubbed by **the same policy, applied client-side at upload time**, in `scrubSecrets()` (`scripts/gds/ship.js`, used by both `ship.js` and `session-digest.js`).
|
|
113
113
|
|
|
114
114
|
This scrubber is **transcript-grade** and **recall-first** (task 1003, which also completed the open token-redaction of task 723): a missed secret is a credential compromise, while over-redacting a non-secret in a BFG digest is merely cosmetic, so when in doubt it redacts. Five layers: (1) literal dynamic values — this run's GDS session token + every secret-shaped **env value** (`collectEnvSecrets()`, e.g. the `MAC_*`/`APPLE_*` signing creds, a baked GDS/DO token); (2) multi-line PEM private-key blocks; (3) the in-scope known shapes from this ADR (provider key prefixes, Stripe `sk_`/`rk_`/`whsec_`, our `gds_`/`pms_` tokens, `Authorization`/`Bearer` headers, JWTs, credentialed DSNs, Apple app-specific passwords); (4) recognised-key `key=value` / JSON-field assignments; (5) a **high-entropy catch-all** (`looksHighEntropySecret()`) over base64url/hex runs ≥20 chars — the net for an *unknown* secret shape. The accepted cost of layer 5 is that high-entropy non-secrets (git SHAs, UUIDs, a 40-hex value shape-identical to a GitHub OAuth client secret) are redacted too; the structured BFG metrics that matter (token/turn counts, tool names, error flags) are separate fields and untouched. The planted-secret corpus in `tests/scrubber_corpus.mjs` is the regression gate — every planted secret must be fully redacted, every benign line must survive — and **gates the full-transcript capture task**: capture must not ship until this passes.
|
|
115
115
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ADR 0024 — Cloneable repo + local-first memory with server-canonical sync
|
|
2
2
|
|
|
3
3
|
**Date:** 2026-05-29
|
|
4
|
-
**Context:** GDS-V3, spike [#230](https://example.com/builders#/task/230) (V3.R04 — Architecture spike: cloneability + local-first memory with server sync). Satisfies done-when criterion C8 (`cloneable-local-memory-server-sync`). Companion to [ADR 0016](
|
|
4
|
+
**Context:** GDS-V3, spike [#230](https://example.com/builders#/task/230) (V3.R04 — Architecture spike: cloneability + local-first memory with server sync). Satisfies done-when criterion C8 (`cloneable-local-memory-server-sync`). Companion to [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) (trust boundary — same enforcement boundary applies here) and [ADR 0022](0022-secrets-policy.md) (no secrets in repo — a precondition for "cloneable").
|
|
5
5
|
**Status:** Accepted.
|
|
6
6
|
|
|
7
7
|
> Numbering note: the spike's done-when named this ADR `<redacted>.md`, but `0016` was already taken by the trust-boundary ADR before this spike was opened. This ADR is **0024**. Same correction the R03 spike (ADR 0016) made for itself.
|
|
@@ -84,7 +84,7 @@ Two-builders-different-builder-id on the same file is impossible by construction
|
|
|
84
84
|
|
|
85
85
|
### 4. Isolation — server enforces `req.builder.id === path_owner.builder_id`
|
|
86
86
|
|
|
87
|
-
All memory endpoints (`POST /memory/sync`, `GET /memory/since`, `GET /memory/files`, `GET /memory/files/:path`) check that the requester's `req.builder.id` matches the row's `builder_id` before reading or writing. Mismatch returns `403 memory_forbidden`. The check happens in the route handler, after `requireBuilder`, before any DB work. Same trust-boundary posture as [ADR 0016](
|
|
87
|
+
All memory endpoints (`POST /memory/sync`, `GET /memory/since`, `GET /memory/files`, `GET /memory/files/:path`) check that the requester's `req.builder.id` matches the row's `builder_id` before reading or writing. Mismatch returns `403 memory_forbidden`. The check happens in the route handler, after `requireBuilder`, before any DB work. Same trust-boundary posture as [ADR 0016](0016-trust-boundary-server-enforced-permissions.md): the server enforces; nothing the builder can edit locally can grant cross-builder access.
|
|
88
88
|
|
|
89
89
|
**Archon forensic exception — read-only.** An Archon-only endpoint `GET /memory/builders/:id/files` exists for restore + forensics use cases (e.g. a builder offboards, Archon needs to inspect their memory; a corrupt file needs restoration). Every Archon read is logged to `audit_log` with `actor_builder_id`, `target_builder_id`, `path`, `reason`. **There is no Archon write endpoint.** Restores happen via `pg_restore` into a sandbox schema, never live. Read-only is the V3 posture; cross-builder *reads* are likely to be relaxed in a later version (e.g. Metics seeing each other's memory for collaboration), but cross-builder *writes* through the API are not on the roadmap. Any future relaxation requires a superseding ADR.
|
|
90
90
|
|
|
@@ -259,7 +259,7 @@ Lars (or a stand-in) runs the full flow with a stopwatch, on a fresh laptop / VM
|
|
|
259
259
|
- No new infra cost. Rides Postgres + existing `pg_dump`.
|
|
260
260
|
- Memory follows the builder across machines and across worktrees on the same machine.
|
|
261
261
|
- A wiped laptop is recoverable in two commands (`git clone` + `/builder-start`).
|
|
262
|
-
- Trust boundary is the same one [ADR 0016](
|
|
262
|
+
- Trust boundary is the same one [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) already established — no new authority concept to reason about.
|
|
263
263
|
- Forensic access exists (for Archon) but is audit-logged, so misuse is visible.
|
|
264
264
|
|
|
265
265
|
**Costs:**
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- **Date:** 2026-05-29 (Phases 1–3); 2026-05-30 (Phases 4–5); Phase 6 + C7 followed.
|
|
5
5
|
- **Deciders:** Lars Kristensen (Archon), Claude
|
|
6
6
|
- **Track:** `internal` (GDS)
|
|
7
|
-
- **Supersedes:** none. Extends [ADR 0010](0010-pms-architecture.md) (GDS architecture), [ADR 0016](
|
|
7
|
+
- **Supersedes:** none. Extends [ADR 0010](0010-pms-architecture.md) (GDS architecture), [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) (trust boundary), [ADR 0017](0017-code-simplification-and-repo-cleanliness.md) (economy lens — the first piece of the Grader's worker decomposition).
|
|
8
8
|
|
|
9
9
|
## Context
|
|
10
10
|
|
|
@@ -45,13 +45,13 @@ red-team completion MONGER
|
|
|
45
45
|
cost/perf
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
**One persistent agent: the Conductor.** Implemented as a `UserPromptSubmit` hook in `.claude/settings.json`. Runs per builder turn. Inherits the builder's rank — no new authority. Output is advisory: it suggests `/builder-redteam` on security-sensitive edits, suggests Grader pre-flight before `/builder-ship`, dispatches BFG after doc edits, and so on. **Conductor proposes; the builder confirms.** Anything that touches a rank-gated route still goes through the existing DB-enforced check ([ADR 0016](
|
|
48
|
+
**One persistent agent: the Conductor.** Implemented as a `UserPromptSubmit` hook in `.claude/settings.json`. Runs per builder turn. Inherits the builder's rank — no new authority. Output is advisory: it suggests `/builder-redteam` on security-sensitive edits, suggests Grader pre-flight before `/builder-ship`, dispatches BFG after doc edits, and so on. **Conductor proposes; the builder confirms.** Anything that touches a rank-gated route still goes through the existing DB-enforced check ([ADR 0016](0016-trust-boundary-server-enforced-permissions.md)) — the Conductor cannot grant or bypass authority.
|
|
49
49
|
|
|
50
50
|
**Three invoked roles, summoned by trigger, not persistent:**
|
|
51
51
|
|
|
52
52
|
- **Grader** (on `/builder-ship`). The ship-time gate. Phase 1 makes it strict (default-fail framing + cross-family Sonnet grading Opus's work + 3-shot unanimous-PASS); Phase 2 decomposes it into a worker panel: *Narc* (semantic completion — task description vs diff), *Quality* (code quality + advisory economy), *Hacker* (security red-team — wraps `/builder-redteam` as a CI gate), *Efficiency Monger* (runtime cost / hot-path performance). Unanimous-PASS gate; non-unanimous falls through to the manual-confirm release valve. Plus a deterministic route-rank pre-pass (C7).
|
|
53
53
|
- **Architect** (quarterly cadence + Conductor nudge). Bounded-scope audits feed `docs/audits/<scope>-<date>.md` + `idea_inbox` seeds. Each quarterly audit becomes the foundational input for the next version's planning session. *No workers yet* — the Architect does its own work flexibly per the user's "delegators without workers do the work themselves" rule.
|
|
54
|
-
- **BFG** (post-ship + pre-cron). Memory + index hygiene at its root — audits CLAUDE.md claims against DB reality, prunes stale references, verifies `[[links]]` resolve. **Widened in [ADR 0026](
|
|
54
|
+
- **BFG** (post-ship + pre-cron). Memory + index hygiene at its root — audits CLAUDE.md claims against DB reality, prunes stale references, verifies `[[links]]` resolve. **Widened in [ADR 0026](0026-bfg-memory-hygiene-and-cross-builder-learning.md) and now shipped (Phase 6 complete):** it also adds DB counter-vs-ledger drift checks (6A.2), scores builders + propagates transferable practice (6B), and operates the audited cross-builder memory WRITE path for dreams + transparent corrections (6C). *No grader-style workers — it does its own work (the "delegators without workers do the work themselves" rule).* Vector-store retrieval still deferred — the MEMORY.md graph + frontmatter suffices.
|
|
55
55
|
|
|
56
56
|
### Why 2 tiers, not 3
|
|
57
57
|
|
|
@@ -73,7 +73,7 @@ Musk's 5-step engineering algorithm: (1) make requirements less dumb, (2) delete
|
|
|
73
73
|
|
|
74
74
|
Reduced cast: **4 agents, not 6** (1 persistent + 3 invoked).
|
|
75
75
|
|
|
76
|
-
**Grader strictness — strict-first, loosen-later.** The grader is the load-bearing first change (its output is consumed by every shipped task). It does not relax during calibration; if it stalls genuine work we tune the prompt, not the gate, with the manual-confirm endpoint (`POST /tasks/:id/confirm`) as the emergency release valve. New grader signals (`shots[]`, `grader_model`, per-worker scores) land in the jsonb `task_grades.signals` column with no migration; top-level `rubric_scores` get the median across shots. This mirrors how the economy lens earned its teeth ([ADR 0017](
|
|
76
|
+
**Grader strictness — strict-first, loosen-later.** The grader is the load-bearing first change (its output is consumed by every shipped task). It does not relax during calibration; if it stalls genuine work we tune the prompt, not the gate, with the manual-confirm endpoint (`POST /tasks/:id/confirm`) as the emergency release valve. New grader signals (`shots[]`, `grader_model`, per-worker scores) land in the jsonb `task_grades.signals` column with no migration; top-level `rubric_scores` get the median across shots. This mirrors how the economy lens earned its teeth ([ADR 0017](0017-code-simplification-and-repo-cleanliness.md)): advisory → calibrate → gate.
|
|
77
77
|
|
|
78
78
|
## Phase plan & implementation history
|
|
79
79
|
|
|
@@ -85,7 +85,7 @@ Built incrementally over six phases, each independently shippable and required t
|
|
|
85
85
|
- **4** — Conductor **session-mediated** dispatch (`scripts/gds/conductor-dispatch.js` runs any specialist on the working diff, reusing the grader-workers machinery).
|
|
86
86
|
- **4.5** — Conductor **autonomous background** dispatch (`conductor-dispatch.js auto-dispatch`): selects the next claimable autonomous task *without a human prompt* and emits its `/builder-claim` directive for a runner to execute. It **proposes, never disposes** in the autonomous path too — the selector emits the directive; the runner + ship pipeline (where ADR 0016's DB gates and the grader still bite) is what claims, builds, and lands. Gated by the same `scripts/gds/autonomy-gate.js` precheck the nightly routines use (master kill-switch + MTD spend brake + no-signal skip), so it is **INERT until `OTB_AUTONOMY_ENABLED=1`**. The candidate feed is the protected-path-filtered `fit:'autonomous'` view (SR-12) — the permission/methodology/deploy core can never be auto-selected.
|
|
87
87
|
- **5** — Architect role + first audit (`scripts/gds/architect-audit.js --scope` → `docs/audits/` + idea_inbox seeds; on-demand, not cron'd).
|
|
88
|
-
- **6** — BFG built out well past bootstrap (doc/index + per-builder memory hygiene, DB counter-vs-ledger drift, cross-builder read + interaction-quality scoring, and the first audited cross-builder memory WRITE path — identity-gated, kill-switched, builder-reversible). Charter: [ADR 0026](
|
|
88
|
+
- **6** — BFG built out well past bootstrap (doc/index + per-builder memory hygiene, DB counter-vs-ledger drift, cross-builder read + interaction-quality scoring, and the first audited cross-builder memory WRITE path — identity-gated, kill-switched, builder-reversible). Charter: [ADR 0026](0026-bfg-memory-hygiene-and-cross-builder-learning.md); session-inefficiency evaluator (cluster 6D): [ADR 0027](0027-bfg-session-inefficiency-evaluator.md).
|
|
89
89
|
- **C7** — the grader's deterministic **route-rank pre-pass** (`src/bongos/route-rank-check.js`, shared via `grader.routeRankPrePass()` by the ship-time panel and `conductor-dispatch.js`): every route must classify to a known rank; write-route `unknown` → hard fail. The deterministic-first → LLM-on-demand pattern; C7's periodic auditor, in-context at ship time.
|
|
90
90
|
|
|
91
91
|
Per-phase scope, rationale, "out of scope", and ship detail (incl. the Phase-1 first-ship calibration data + the `Number(null)=0` self-ship learning) live in the shipping tasks + the session logs — this ADR is the decision record, not the changelog. Phase tasks: [#395](https://example.com/builders#/task/395) (1) · [#410](https://example.com/builders#/task/410)/[#413](https://example.com/builders#/task/413)/[#416](https://example.com/builders#/task/416)/[#421](https://example.com/builders#/task/421)/[#423](https://example.com/builders#/task/423) (2) · [#427](https://example.com/builders#/task/427) (3) · [#439](https://example.com/builders#/task/439) (4) · [#459](https://example.com/builders#/task/459) (5) · [#442](https://example.com/builders#/task/442)–[#448](https://example.com/builders#/task/448) (6) · [#475](https://example.com/builders#/task/475) (C7) · [#458](https://example.com/builders#/task/458) (4.5).
|
|
@@ -96,8 +96,8 @@ Per-phase scope, rationale, "out of scope", and ship detail (incl. the Phase-1 f
|
|
|
96
96
|
|
|
97
97
|
- The trust gate at `/builder-ship` actually bites. Calibration data — not vibes — drives future tightening.
|
|
98
98
|
- Cost is ~neutral: 3× Sonnet ≈ 1× Opus (prior). Grader cost-per-shipped-task does not balloon.
|
|
99
|
-
- Architecture-ready for per-builder model preferences ([ADR 0021](
|
|
100
|
-
- Trust boundary preserved: nothing here grants new permissions; the Conductor (Phase 3+) inherits builder rank and proposes, never disposes ([ADR 0016](
|
|
99
|
+
- Architecture-ready for per-builder model preferences ([ADR 0021](0021-per-builder-skill-model-preferences.md)): when GDS-V4 ships builder-configurable model allocation, the `selectGraderModel(builderModel)` function becomes the obvious extension point.
|
|
100
|
+
- Trust boundary preserved: nothing here grants new permissions; the Conductor (Phase 3+) inherits builder rank and proposes, never disposes ([ADR 0016](0016-trust-boundary-server-enforced-permissions.md) stays load-bearing).
|
|
101
101
|
- The original Delegators (Project Manager, Janitor) are *deleted* rather than built — the Musk rule applied to ourselves.
|
|
102
102
|
|
|
103
103
|
**Bad / accepted:**
|
|
@@ -115,9 +115,9 @@ Per-phase scope, rationale, "out of scope", and ship detail (incl. the Phase-1 f
|
|
|
115
115
|
## References
|
|
116
116
|
|
|
117
117
|
- [ADR 0010](0010-pms-architecture.md) — GDS (then PMS) architecture
|
|
118
|
-
- [ADR 0016](
|
|
119
|
-
- [ADR 0017](
|
|
120
|
-
- [ADR 0021](
|
|
118
|
+
- [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) — trust boundary (Conductor must not bypass)
|
|
119
|
+
- [ADR 0017](0017-code-simplification-and-repo-cleanliness.md) — economy lens (first Grader worker, retroactively)
|
|
120
|
+
- [ADR 0021](0021-per-builder-skill-model-preferences.md) — per-builder model preferences (Phase 1's hardcoded Sonnet generalizes here)
|
|
121
121
|
- Anthropic, "Building Effective Agents" (Schluntz & Zhang, Dec 2024) — orchestrator-workers and evaluator-optimizer patterns
|
|
122
122
|
- Anthropic, "How we built our multi-agent research system" (Engineering blog, 2025) — empirical 2-tier orchestration, ~15× token cost
|
|
123
123
|
- Zheng et al., "Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena" (NeurIPS 2023) — same-family judge inflation
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ADR 0025 — Offsite backup vendor: DigitalOcean Spaces
|
|
2
2
|
|
|
3
3
|
**Date:** 2026-05-30
|
|
4
|
-
**Context:** Task [#415](https://example.com/builders#/task/415) (V3.R62-offsite), claim `#338`, GDS-V3 criterion C8 ("memory is local-first, server-canonical on ship" — which depends on the GDS DB surviving whole-droplet loss). Companion to the local nightly backup filed by [#412](https://example.com/builders#/task/412) (V3.R62-precondition, [`docs/recipes/gds-db-backup.md`](../recipes/gds-db-backup.md)) and the secrets policy in [ADR 0022](0022-secrets-policy.md). Sits under [ADR 0024 §5](
|
|
4
|
+
**Context:** Task [#415](https://example.com/builders#/task/415) (V3.R62-offsite), claim `#338`, GDS-V3 criterion C8 ("memory is local-first, server-canonical on ship" — which depends on the GDS DB surviving whole-droplet loss). Companion to the local nightly backup filed by [#412](https://example.com/builders#/task/412) (V3.R62-precondition, [`docs/recipes/gds-db-backup.md`](../recipes/gds-db-backup.md)) and the secrets policy in [ADR 0022](0022-secrets-policy.md). Sits under [ADR 0024 §5](0024-cloneable-repo-local-first-memory.md) (backup cadence).
|
|
5
5
|
**Status:** Accepted.
|
|
6
6
|
|
|
7
7
|
## Problem
|
|
@@ -39,6 +39,6 @@ This positional decode is brittle — reorder the criteria and old prose referen
|
|
|
39
39
|
## Consequences
|
|
40
40
|
|
|
41
41
|
- **One-call status.** `/status C8` answers in a single request what previously took ~10. The public dashboard can adopt the same endpoint.
|
|
42
|
-
- **The Conductor stays advisory + zero-cost.** It gains one regex trigger that *routes* status-intent prompts to `/status` (proposes, never disposes; no LLM call) — it does not answer questions itself. Consistent with [ADR 0024 (MAS)](
|
|
42
|
+
- **The Conductor stays advisory + zero-cost.** It gains one regex trigger that *routes* status-intent prompts to `/status` (proposes, never disposes; no LLM call) — it does not answer questions itself. Consistent with [ADR 0024 (MAS)](0024-multi-agent-system-architecture.md) Phase 3.
|
|
43
43
|
- **Follow-up needed:** task creation does not yet populate `task_criteria`, so tasks created after the backfill are unlinked until a manage endpoint / planning-flow wire-up lands. Filed as a follow-up task at ship time. Until then `/status` under-counts new work, which `unattributed_tasks` makes visible.
|
|
44
44
|
- **No authority change.** The endpoint is public read-only (same posture as `/versions/:id/done-when`); the join table carries no permission semantics. ADR 0016 trust boundary is untouched.
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
- **Track:** `internal` (GDS)
|
|
7
7
|
- **Context task:** GDS-V3 [#441](https://example.com/builders#/task/441) (this design task — ADR + task breakdown only; no implementation).
|
|
8
8
|
|
|
9
|
-
> **Numbering note:** this ADR was authored as `0025` but renumbered to **0026** on the same day, after a merge from `main` surfaced an already-shipped [`0025` — Offsite backup vendor](
|
|
10
|
-
- **Extends:** [ADR 0024 — Multi-Agent System architecture](
|
|
9
|
+
> **Numbering note:** this ADR was authored as `0025` but renumbered to **0026** on the same day, after a merge from `main` surfaced an already-shipped [`0025` — Offsite backup vendor](0025-offsite-backup-vendor-digitalocean-spaces.md) (task [#415](https://example.com/builders#/task/415)). The shipped ADR keeps `0025`; this one moves. The backlog implementation tasks **[#442](https://example.com/builders#/task/442)–[#448](https://example.com/builders#/task/448)** were filed *before* the renumber and so reference this ADR as "ADR 0025" in their descriptions (the GDS has no description-edit endpoint and there was no DB access to correct them in-session). The sub-phase labels (**6A.1 … 6C.3**) are stable and unambiguous — when a task says "ADR 0025 section 6A.1", read **this** ADR (0026), section 6A.1.
|
|
10
|
+
- **Extends:** [ADR 0024 — Multi-Agent System architecture](0024-multi-agent-system-architecture.md) (the BFG is its Phase 6); [ADR 0024 — Cloneable repo + local-first memory](0024-cloneable-repo-local-first-memory.md) (the `builder_memory` store this operates on); [ADR 0016 — Trust boundary](0016-trust-boundary-server-enforced-permissions.md) (this ADR deliberately and narrowly *punctures* the no-cross-builder-write rule — recorded here as a conscious exception). Touches the karma model ([migration 040](../../migrations/040_builder_karma.sql)) and the memory schema ([migration 054](../../migrations/054_builder_memory.sql)).
|
|
11
11
|
|
|
12
12
|
## Context
|
|
13
13
|
|
|
14
|
-
The **BFG** is the post-ship / pre-cron role in the MAS ([ADR 0024-mas](
|
|
14
|
+
The **BFG** is the post-ship / pre-cron role in the MAS ([ADR 0024-mas](0024-multi-agent-system-architecture.md)). Its Phase-6 charter there was deliberately narrow: *"memory hygiene — audit CLAUDE.md claims against DB reality, prune stale references, verify `[[links]]` resolve."* No code has been written yet.
|
|
15
15
|
|
|
16
16
|
On 2026-05-30 Lars expanded the BFG's remit to **two standing objectives**:
|
|
17
17
|
|
|
@@ -22,7 +22,7 @@ This ADR records the architecture and, critically, the **boundaries** that turn
|
|
|
22
22
|
|
|
23
23
|
### What the substrate already gives us
|
|
24
24
|
|
|
25
|
-
- **Builder memory is server-canonical and per-builder isolated** — [`builder_memory`](../../src/bongos/routes/memory.js), `PRIMARY KEY (builder_id, path)`. The *only* cross-builder access that exists today is an **Archon-only, audit-logged, read-only** forensic path. **There is no cross-builder *write* path at all** — that was a conscious decision ([ADR 0016](
|
|
25
|
+
- **Builder memory is server-canonical and per-builder isolated** — [`builder_memory`](../../src/bongos/routes/memory.js), `PRIMARY KEY (builder_id, path)`. The *only* cross-builder access that exists today is an **Archon-only, audit-logged, read-only** forensic path. **There is no cross-builder *write* path at all** — that was a conscious decision ([ADR 0016](0016-trust-boundary-server-enforced-permissions.md), [ADR 0024-memory](0024-cloneable-repo-local-first-memory.md) §4).
|
|
26
26
|
- **Karma** ([`karma_log`](../../migrations/040_builder_karma.sql)) is the existing good-citizenship reputation ledger (append-only, `granted_by` records who drove a delta, `NULL` = system).
|
|
27
27
|
- **Cron roles** live as `SKILL.md` files under [`.claude/scheduled-tasks/`](../../.claude/scheduled-tasks/); the read-only `overnight-code-review` routine is the closest existing pattern.
|
|
28
28
|
|
|
@@ -50,7 +50,7 @@ Read-only auditor. Findings land as `idea_inbox` rows (one per finding, like `ov
|
|
|
50
50
|
|
|
51
51
|
### 6C — Dreams & correction (the write path — the load-bearing part)
|
|
52
52
|
|
|
53
|
-
This sub-phase creates the **first cross-builder memory write capability** in the system. It is the deliberate, bounded exception to [ADR 0016](
|
|
53
|
+
This sub-phase creates the **first cross-builder memory write capability** in the system. It is the deliberate, bounded exception to [ADR 0016](0016-trust-boundary-server-enforced-permissions.md).
|
|
54
54
|
|
|
55
55
|
**Dreams (beneficial writes).** Lars chose **direct write** (audited + visible) over propose-only, for immediacy. The BFG writes the entry directly into the target builder's memory, constrained by:
|
|
56
56
|
- a dedicated, clearly-marked location — e.g. `bfg/dream-<slug>.md` (or a fenced `## BFG dreams` block) — never overwriting a builder's own files;
|
|
@@ -78,19 +78,19 @@ The BFG runs as a `SKILL.md` scheduled routine (post-ship / pre-cron cadence) an
|
|
|
78
78
|
| **6B.2** | Transferable-pattern extraction from top performers + adoption-suggestion generation. | Good practice propagates; the "most creative experience" objective gets teeth. |
|
|
79
79
|
| **6C.1** | Migration: BFG service principal (system builder, no-claim/no-example) + cross-builder memory **write** endpoint (audited, namespaced, attributed) + `karma_log` reason `bfg_correction`. | The write substrate + trust-boundary exception land in one reviewable unit. |
|
|
80
80
|
| **6C.2** | Wire dream-writes + transparent corrections into the BFG routine; kill-switch; builder-visible attribution; delete affordance. | Dreams + correction work end-to-end, safely. |
|
|
81
|
-
| **6C.3** | Update [ADR 0024-mas](
|
|
81
|
+
| **6C.3** | Update [ADR 0024-mas](0024-multi-agent-system-architecture.md) Phase-6 row + CLAUDE.md MAS index line. (Deferred out of [#441](https://example.com/builders#/task/441) — `CLAUDE.md` / `0024` are held by the active Phase-4 claim `#439`.) | The index reflects the shipped BFG. |
|
|
82
82
|
|
|
83
|
-
Each sub-phase must answer "is this earning its tokens?" before the next is built — the Musk gate, same as [ADR 0024-mas](
|
|
83
|
+
Each sub-phase must answer "is this earning its tokens?" before the next is built — the Musk gate, same as [ADR 0024-mas](0024-multi-agent-system-architecture.md).
|
|
84
84
|
|
|
85
|
-
> **Sibling capability cluster — 6D (session-inefficiency evaluator), recorded in [ADR 0027](
|
|
85
|
+
> **Sibling capability cluster — 6D (session-inefficiency evaluator), recorded in [ADR 0027](0027-bfg-session-inefficiency-evaluator.md).** The 6A/6B/6C clusters above cover the BFG's *hygiene* and *cross-builder memory learning* objectives. A later, separately-chartered cluster — **6D** — serves the same "best building experience" objective from a different angle: it ingests uploaded session transcripts and auto-runs the #506-style post-mortem across all sessions to surface systemic build-process waste (and mine top performers for good practice). It reuses this charter's §6C transparent-note path to deliver per-builder findings. See [ADR 0027](0027-bfg-session-inefficiency-evaluator.md); build tasks GDS-V4 [#540](https://example.com/builders#/task/540)–[#545](https://example.com/builders#/task/545).
|
|
86
86
|
|
|
87
87
|
## Alternatives considered
|
|
88
88
|
|
|
89
89
|
- **Covert "nightmares" (rejected).** The original ask imagined planting *false or harmful* memories to covertly worsen a misbehaving builder. Rejected outright: it is deception that causes real harm (wasted work, decisions seeded by lies), it has no consent, and an audit trail does not redeem it. Transparent correction (a visible, attributed note + a karma dock) achieves the same steering with none of that. This is the load-bearing rejection of this ADR.
|
|
90
90
|
- **Propose-only writes vs direct writes.** Propose-only (the BFG drops a clearly-marked *suggestion* the builder must accept) best preserves the isolation/consent spirit. Lars chose **direct write** for immediacy on "obvious improvements." We keep the consent spirit alive through visible attribution + namespaced files + delete-ability + per-write audit, and accept the residual risk (memory changing between sessions) in §Consequences.
|
|
91
91
|
- **Karma-only correction (no memory write).** Considered: never touch a misbehaving builder's memory, only dock karma + flag for Archon. Rejected as the *default* because a karma delta alone doesn't tell the builder *what* to change; the visible corrective note carries the actionable feedback. (Karma-only remains the right move when there's nothing constructive to write.)
|
|
92
|
-
- **Amend ADR 0024 vs a standalone ADR.** The BFG is Phase 6 of [ADR 0024-mas](
|
|
93
|
-
- **Vector store / semantic memory for hygiene + 6B scoring.** Deferred, consistent with [ADR 0024-mas](
|
|
92
|
+
- **Amend ADR 0024 vs a standalone ADR.** The BFG is Phase 6 of [ADR 0024-mas](0024-multi-agent-system-architecture.md), so amending it was the obvious option. Chosen instead to write a standalone ADR because the new **cross-builder write path is a trust-boundary decision** that extends [ADR 0016](0016-trust-boundary-server-enforced-permissions.md) — significant enough to deserve its own record rather than a table-row footnote.
|
|
93
|
+
- **Vector store / semantic memory for hygiene + 6B scoring.** Deferred, consistent with [ADR 0024-mas](0024-multi-agent-system-architecture.md)'s own "vector-store implementation deferred" call. The current markdown `MEMORY.md` graph + frontmatter is sufficient for 6A/6B; revisit only if manual + heuristic analysis proves insufficient.
|
|
94
94
|
|
|
95
95
|
## Consequences
|
|
96
96
|
|
|
@@ -110,8 +110,8 @@ Each sub-phase must answer "is this earning its tokens?" before the next is buil
|
|
|
110
110
|
|
|
111
111
|
## References
|
|
112
112
|
|
|
113
|
-
- [ADR 0024 — Multi-Agent System architecture](
|
|
114
|
-
- [ADR 0024 — Cloneable repo + local-first memory](
|
|
115
|
-
- [ADR 0016 — Trust boundary](
|
|
113
|
+
- [ADR 0024 — Multi-Agent System architecture](0024-multi-agent-system-architecture.md) — the BFG is Phase 6
|
|
114
|
+
- [ADR 0024 — Cloneable repo + local-first memory](0024-cloneable-repo-local-first-memory.md) — the `builder_memory` store + §4 isolation
|
|
115
|
+
- [ADR 0016 — Trust boundary](0016-trust-boundary-server-enforced-permissions.md) — the rule this ADR narrowly excepts
|
|
116
116
|
- [migration 040](../../migrations/040_builder_karma.sql) — karma ledger (correction deltas)
|
|
117
117
|
- [migration 054](../../migrations/054_builder_memory.sql) — memory schema (read + write target)
|