@bongos/core 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bongos-core.json +5727 -0
- package/.claude/skills/blocker-review/SKILL.md +91 -0
- package/.claude/skills/blocker-solve/SKILL.md +96 -0
- package/.claude/skills/builder-backup/SKILL.md +54 -0
- package/.claude/skills/builder-box/SKILL.md +45 -0
- package/.claude/skills/builder-claim/SKILL.md +76 -0
- package/.claude/skills/builder-connect/SKILL.md +59 -0
- package/.claude/skills/builder-cost/SKILL.md +47 -0
- package/.claude/skills/builder-end/SKILL.md +81 -0
- package/.claude/skills/builder-exit/SKILL.md +88 -0
- package/.claude/skills/builder-key/SKILL.md +40 -0
- package/.claude/skills/builder-reauth/SKILL.md +50 -0
- package/.claude/skills/builder-redteam/SKILL.md +109 -0
- package/.claude/skills/builder-release/SKILL.md +41 -0
- package/.claude/skills/builder-setup/SKILL.md +62 -0
- package/.claude/skills/builder-ship/SKILL.md +79 -0
- package/.claude/skills/builder-stage/SKILL.md +51 -0
- package/.claude/skills/builder-start/SKILL.md +46 -0
- package/.claude/skills/close-box/SKILL.md +43 -0
- package/.claude/skills/design-sync/SKILL.md +69 -0
- package/.claude/skills/dev/SKILL.md +49 -0
- package/.claude/skills/feedback/SKILL.md +32 -0
- package/.claude/skills/figma-design-sync/SKILL.md +74 -0
- package/.claude/skills/goal-review/SKILL.md +89 -0
- package/.claude/skills/idea-triage/SKILL.md +144 -0
- package/.claude/skills/ideate/SKILL.md +82 -0
- package/.claude/skills/merge-mode/SKILL.md +169 -0
- package/.claude/skills/new-project/SKILL.md +108 -0
- package/.claude/skills/otb-character-review/SKILL.md +71 -0
- package/.claude/skills/otb-design-review/SKILL.md +47 -0
- package/.claude/skills/otb-feedback-capture/SKILL.md +45 -0
- package/.claude/skills/otb-figma-sync/SKILL.md +54 -0
- package/.claude/skills/otb-tile-generate/SKILL.md +45 -0
- package/.claude/skills/paint/SKILL.md +70 -0
- package/.claude/skills/planning-session/SKILL.md +299 -0
- package/.claude/skills/priority-session/SKILL.md +134 -0
- package/.claude/skills/read-session-export/SKILL.md +58 -0
- package/.claude/skills/recall/SKILL.md +52 -0
- package/.claude/skills/session-handoff/SKILL.md +46 -0
- package/.claude/skills/status/SKILL.md +33 -0
- package/.devcontainer/Dockerfile +69 -0
- package/.devcontainer/README.md +73 -0
- package/.devcontainer/devcontainer-lock.json +19 -0
- package/.devcontainer/devcontainer.json +93 -0
- package/.devcontainer/healthcheck.sh +84 -0
- package/.devcontainer/init-firewall.sh +198 -0
- package/.devcontainer/post-create.sh +153 -0
- package/.dockerignore +36 -0
- package/.env.local.example +32 -0
- package/.gitattributes +83 -0
- package/.gitignore +91 -0
- package/CLAUDE.md +242 -0
- package/CODE_OF_CONDUCT.md +46 -0
- package/CONTRIBUTING.md +51 -0
- package/Dockerfile +46 -0
- package/GOVERNANCE.md +44 -0
- package/LICENSE +661 -0
- package/README.md +88 -0
- package/bin/bongos.js +222 -0
- package/clients/bongos-client/README.md +48 -0
- package/clients/bongos-client/bongos-client.global.js +617 -0
- package/clients/bongos-client/examples/hello-world.mjs +62 -0
- package/clients/bongos-client/index.cjs +619 -0
- package/clients/bongos-client/index.d.ts +793 -0
- package/clients/bongos-client/index.mjs +614 -0
- package/clients/bongos-client/package.json +32 -0
- package/config/branding.neutral.json +60 -0
- package/config/design-tokens.neutral.json +51 -0
- package/config/design-tokens.schema.json +96 -0
- package/config/modules.neutral.json +9 -0
- package/docker-compose.yml +52 -0
- package/docker-entrypoint.sh +30 -0
- package/docs/adr/0001-stack-choice-single-vps.md +45 -0
- package/docs/adr/0002-digitalocean-over-hetzner.md +27 -0
- package/docs/adr/0003-cloudflare-origin-cert-over-letsencrypt.md +35 -0
- package/docs/adr/0004-amazonprimea-name-and-trademark-acceptance.md +45 -0
- package/docs/adr/0005-invisible-other-players-in-v1.md +37 -0
- package/docs/adr/0006-singleton-worldroom-plus-queueroom.md +30 -0
- package/docs/adr/0007-persistent-identity-via-localstorage-uuid.md +31 -0
- package/docs/adr/0008-family-based-tile-generation.md +86 -0
- package/docs/adr/0008-google-chat-oauth-user-auth.md +37 -0
- package/docs/adr/0009-autotile-architecture.md +181 -0
- package/docs/adr/0010-pms-architecture.md +70 -0
- package/docs/adr/0011-terrain-id-rendering-model.md +174 -0
- package/docs/adr/0012-ground-object-cell-split.md +208 -0
- package/docs/adr/0013-paths-as-object-overlays-with-autotile-dispatch.md +158 -0
- package/docs/adr/0014-families-canonical-over-vocabulary.md +103 -0
- package/docs/adr/0015-task-dependencies-and-auto-promotion.md +125 -0
- package/docs/adr/0016-trust-boundary-server-enforced-permissions.md +132 -0
- package/docs/adr/0017-code-simplification-and-repo-cleanliness.md +74 -0
- package/docs/adr/0018-three-rank-model-goes-live.md +97 -0
- package/docs/adr/0019-red-team-bounty-payout-table.md +52 -0
- package/docs/adr/0020-security-model-public-stub.md +70 -0
- package/docs/adr/0021-per-builder-skill-model-preferences.md +99 -0
- package/docs/adr/0022-secrets-policy.md +124 -0
- package/docs/adr/0023-kind-multipliers-and-idea-bonus.md +118 -0
- package/docs/adr/0024-cloneable-repo-local-first-memory.md +277 -0
- package/docs/adr/0024-multi-agent-system-architecture.md +125 -0
- package/docs/adr/0025-offsite-backup-vendor-digitalocean-spaces.md +59 -0
- package/docs/adr/0025-structured-criterion-task-link.md +44 -0
- package/docs/adr/0026-bfg-memory-hygiene-and-cross-builder-learning.md +117 -0
- package/docs/adr/0027-bfg-session-inefficiency-evaluator.md +170 -0
- package/docs/adr/0028-honest-llm-spend-accounting.md +109 -0
- package/docs/adr/0029-status-page-outage-resilience.md +59 -0
- package/docs/adr/0030-builders-hall-live-updates.md +59 -0
- package/docs/adr/0031-cloud-dev-environments-for-builders.md +222 -0
- package/docs/adr/0032-discord-mirror-of-gds.md +50 -0
- package/docs/adr/0033-discord-bot-service-principal.md +82 -0
- package/docs/adr/0034-thetes-graduated-newcomer-rank.md +53 -0
- package/docs/adr/0035-builder-onboarding-three-paths.md +128 -0
- package/docs/adr/0036-builders-subdomain-and-ui-reorg.md +40 -0
- package/docs/adr/0037-discord-channel-management.md +51 -0
- package/docs/adr/0038-chromebook-ttyd-cloudflare-tunnel.md +111 -0
- package/docs/adr/0039-setup-first-onboarding-ux.md +49 -0
- package/docs/adr/0040-remote-control-default-browser-onramp.md +47 -0
- package/docs/adr/0041-temporary-grader-bypass-killswitch.md +40 -0
- package/docs/adr/0042-builder-self-deploy-ci-auto-merge.md +82 -0
- package/docs/adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md +74 -0
- package/docs/adr/0044-mediterranean-palette-replacement.md +73 -0
- package/docs/adr/0044-per-box-live-game-preview.md +57 -0
- package/docs/adr/0045-devbox-desktop-app.md +133 -0
- package/docs/adr/0046-sandbox-first-review-gate.md +72 -0
- package/docs/adr/0047-discord-bugs-intake-anti-abuse.md +36 -0
- package/docs/adr/0048-works-in-progress-ia-split.md +32 -0
- package/docs/adr/0049-split-parallel-safety-contract.md +46 -0
- package/docs/adr/0050-device-flow-admission-invite-gated-by-default.md +43 -0
- package/docs/adr/0051-full-session-transcript-corpus.md +57 -0
- package/docs/adr/0052-sandbox-for-everyone-game-only-preview.md +70 -0
- package/docs/adr/0053-scoped-dev-box-session.md +55 -0
- package/docs/adr/0054-session-token-reward-cost-plus.md +63 -0
- package/docs/adr/0055-server-mediated-branch-publish.md +47 -0
- package/docs/adr/0056-prod-deploy-script-mirror-and-healthcheck-retry.md +62 -0
- package/docs/adr/0057-container-cost-ledger.md +28 -0
- package/docs/adr/0057-discord-archon-approval-channels.md +64 -0
- package/docs/adr/0058-automatic-gate-surface-gatekeeper.md +64 -0
- package/docs/adr/0059-single-approval-remove-devbox-approval-gate.md +37 -0
- package/docs/adr/0060-gds-retrieval-layer.md +97 -0
- package/docs/adr/0061-context-layer-decomposition.md +61 -0
- package/docs/adr/0062-medusa-instance-model-decoupling.md +107 -0
- package/docs/adr/0063-generated-repo-map-symbol-skeleton.md +44 -0
- package/docs/adr/0064-rename-medusa-to-cloud-bongos.md +49 -0
- package/docs/adr/0065-agpl-nonprofit-ai-first-governance.md +69 -0
- package/docs/adr/0066-generated-file-map-sections.md +51 -0
- package/docs/adr/0067-session-start-fast-forward-pull.md +43 -0
- package/docs/adr/0068-shared-art-key-for-newcomers.md +38 -0
- package/docs/adr/0069-hall-live-channel-sse-decouple.md +35 -0
- package/docs/adr/0070-deterministic-session-card-delivery.md +44 -0
- package/docs/adr/0071-box-confirm-before-destroyed-and-drift-reconcile.md +59 -0
- package/docs/adr/0072-bongos-app-mac-signed-first-windows-deferred.md +35 -0
- package/docs/adr/0072-dev-box-code-staleness-visibility.md +39 -0
- package/docs/adr/0073-builder-needs-signal-and-byok-gemini-key.md +64 -0
- package/docs/adr/0073-secrets-scan-exclude-uri-detector.md +37 -0
- package/docs/adr/0074-memory-map-stays-light.md +32 -0
- package/docs/adr/0075-per-system-cost-attribution.md +37 -0
- package/docs/adr/0076-in-session-deterministic-compaction.md +58 -0
- package/docs/adr/0077-content-addressed-llm-cache.md +32 -0
- package/docs/adr/0078-deterministic-first-cron.md +48 -0
- package/docs/adr/0079-value-gated-autonomous-engagement.md +39 -0
- package/docs/adr/0080-llm-cache-api-transport-and-trust-model.md +46 -0
- package/docs/adr/0081-tool-agnostic-design-layer.md +62 -0
- package/docs/adr/0082-productized-key-storage-provisioning.md +32 -0
- package/docs/adr/0082-server-side-merge-conflict-auto-resolution.md +55 -0
- package/docs/adr/0083-modular-architecture-strangler-build-plan.md +143 -0
- package/docs/adr/0084-auto-derived-per-task-rank-floor.md +86 -0
- package/docs/adr/0085-remove-default-per-builder-spend-cap.md +39 -0
- package/docs/adr/0086-goal-scoped-work-hierarchy.md +123 -0
- package/docs/adr/0087-bongos-app-architecture-and-handoff-contract.md +49 -0
- package/docs/adr/0087-compete-on-governance-not-tooling-cursor.md +65 -0
- package/docs/adr/0088-consistent-character-generative-animation.md +169 -0
- package/docs/adr/0089-modular-multi-model-adversarial-grader.md +179 -0
- package/docs/adr/0090-metic-task-authoring.md +73 -0
- package/docs/adr/0091-bounding-the-kernel-and-db-carve.md +106 -0
- package/docs/adr/0092-hosting-module-and-on-prem-target.md +117 -0
- package/docs/adr/0093-tranche-2-core-carve-sequence.md +72 -0
- package/docs/adr/0094-repo-atlas-self-drawing-codebase-map.md +49 -0
- package/docs/adr/0095-borrowed-memory-and-retrieval-concepts.md +65 -0
- package/docs/adr/0095-cross-agent-context-management.md +58 -0
- package/docs/adr/0096-require-reward-before-workable.md +209 -0
- package/docs/adr/0097-one-active-claim-per-session-and-worktree-binding.md +46 -0
- package/docs/adr/0097-retroactive-reward-backfill.md +124 -0
- package/docs/adr/0098-public-mirror-publish-manifest.md +92 -0
- package/docs/adr/0099-delayed-redacted-mirror-export.md +55 -0
- package/docs/adr/0100-two-repo-instance-model.md +60 -0
- package/docs/adr/0101-goal-hierarchy-phase-5-judge-membership-reward.md +90 -0
- package/docs/adr/0102-finish-bounding-the-kernel.md +36 -0
- package/docs/adr/0103-core-first-extraction-cloud-bongos-trunk.md +70 -0
- package/docs/adr/0103-gdsv4-bongos-consolidation.md +28 -0
- package/docs/adr/0104-trust-gds-api-channel-in-auto-mode.md +42 -0
- package/docs/adr/0105-instance-seed-migrations-out-of-core.md +47 -0
- package/docs/adr/0106-goal-owner-manager-authority.md +84 -0
- package/docs/adr/0107-module-upstreaming-contribution-to-core-catalog.md +83 -0
- package/docs/adr/0108-instance-composition-configurable-root.md +87 -0
- package/docs/adr/0109-self-describing-openapi-and-hosted-docs.md +44 -0
- package/docs/adr/0110-untrack-whole-file-generated-nav-docs.md +49 -0
- package/docs/adr/0111-instance-hosting-provisioning-module.md +135 -0
- package/docs/adr/0112-private-goals-invitations-join-requests.md +72 -0
- package/docs/adr/0113-sandbox-studio-descope-superseded-by-0044-0052.md +41 -0
- package/docs/adr/0114-instance-docs-discovery-contract.md +32 -0
- package/docs/adr/0115-scheduled-routines-portability.md +31 -0
- package/docs/adr/0116-api-error-envelope-and-code-taxonomy.md +62 -0
- package/docs/adr/0117-api-versioning-and-deprecation-policy.md +50 -0
- package/docs/adr/0118-api-contract-source-of-truth-code-first.md +47 -0
- package/docs/adr/0119-api-pagination-contract.md +34 -0
- package/docs/adr/0120-pay-on-land-and-builder-owned-rebase-gate.md +108 -0
- package/docs/adr/0121-greenfield-vs-brownfield-onboarding-adopt-existing-repo.md +97 -0
- package/docs/adr/0122-onboarding-diagram-renders-deploy-rendered-off-git.md +43 -0
- package/docs/adr/0123-box-idle-sweep-autosave-before-destroy.md +36 -0
- package/docs/adr/0124-typed-api-response-bodies.md +37 -0
- package/docs/adr/0125-control-plane-scaffolds-standalone-instance-repo.md +36 -0
- package/docs/adr/0126-dedicated-cloudbongos-control-plane-droplet.md +30 -0
- package/docs/adr/0127-cross-box-fleet-observability.md +64 -0
- package/docs/adr/0128-provisioning-runner-privilege-and-db-auth-model.md +46 -0
- package/docs/adr/0129-cloudbongos-control-plane-pull-deploy.md +34 -0
- package/docs/adr/0130-provision-remote-exec-over-ssh.md +61 -0
- package/docs/adr/0131-rank-scoped-skill-visibility.md +47 -0
- package/docs/adr/0132-cohost-fleet-control-plane-migration.md +54 -0
- package/docs/adr/0133-github-app-manifest-onboarding-signin.md +42 -0
- package/docs/adr/0134-private-first-npm-distribution.md +38 -0
- package/docs/adr/README.md +208 -0
- package/docs/api/openapi.json +13720 -0
- package/docs/api-reference.md +437 -0
- package/docs/architecture.md +244 -0
- package/docs/branding-contract.md +66 -0
- package/docs/branding-fill-prompt.md +25 -0
- package/docs/canonical-permissions.md +241 -0
- package/docs/design/container-exterior-tiles.md +49 -0
- package/docs/design/container-exterior.md +81 -0
- package/docs/design/container-interior.md +77 -0
- package/docs/design/modular-architecture/00-research-report.md +107 -0
- package/docs/design/modular-architecture/01-architecture.md +125 -0
- package/docs/design/modular-architecture/02-module-map.md +116 -0
- package/docs/design/modular-architecture/03-builder-flows.md +104 -0
- package/docs/design/modular-architecture/04-module-lifecycle.md +62 -0
- package/docs/design/modular-architecture/README.md +27 -0
- package/docs/design/vanilla-hall-ui-redesign-scope.md +284 -0
- package/docs/design/world-map-scroll.md +41 -0
- package/docs/design-contract.md +320 -0
- package/docs/file-map.md +418 -0
- package/docs/handoff-template.md +92 -0
- package/docs/modules-contract.md +293 -0
- package/docs/onboarding/browser-terminal-guide.md +73 -0
- package/docs/onboarding/diagrams/01-task-lifecycle.mmd +28 -0
- package/docs/onboarding/diagrams/02-rank-ladder.mmd +54 -0
- package/docs/onboarding/diagrams/03-drachmae-karma.mmd +37 -0
- package/docs/onboarding/diagrams/04-architecture.mmd +51 -0
- package/docs/onboarding/diagrams/05-versioning.mmd +29 -0
- package/docs/onboarding/diagrams/README.md +94 -0
- package/docs/onboarding/diagrams/assertions.json +170 -0
- package/docs/onboarding/diagrams/puppeteer-config.json +1 -0
- package/docs/onboarding/diagrams/render-config.json +9 -0
- package/docs/onboarding/drachmae-and-karma.md +178 -0
- package/docs/onboarding/primer.md +202 -0
- package/docs/project-context.template.md +67 -0
- package/docs/recipes/README.md +35 -0
- package/docs/recipes/audit-replay.md +100 -0
- package/docs/recipes/bongos-cli-release.md +66 -0
- package/docs/recipes/builder-box-lifecycle.md +152 -0
- package/docs/recipes/claude-design-loop.md +143 -0
- package/docs/recipes/claude-gemini-bongos-doors.md +155 -0
- package/docs/recipes/cloudbongos-staging-gate.md +139 -0
- package/docs/recipes/cloudbongos-standup.md +111 -0
- package/docs/recipes/devbox-app-release.md +93 -0
- package/docs/recipes/devbox-app-windows-test.md +128 -0
- package/docs/recipes/failed-ship-recovery-proof.md +102 -0
- package/docs/recipes/figma-design-loop.md +129 -0
- package/docs/recipes/gds-db-backup.md +255 -0
- package/docs/recipes/instance-deploy.md +37 -0
- package/docs/recipes/managed-settings-remote-control.md +416 -0
- package/docs/recipes/memory-backup.md +71 -0
- package/docs/recipes/memory-sync-conflicts.md +98 -0
- package/docs/recipes/multi-builder-merge.md +78 -0
- package/docs/recipes/ops-gotchas.md +212 -0
- package/docs/recipes/overnight-builder.md +53 -0
- package/docs/recipes/packaging-the-core.md +49 -0
- package/docs/recipes/parallel-load-results-2026-05-30.md +63 -0
- package/docs/recipes/parallel-load-test.md +32 -0
- package/docs/recipes/pixel-art-pipeline.md +411 -0
- package/docs/recipes/private-npm-distribution.md +79 -0
- package/docs/recipes/search-index-ingestion.md +67 -0
- package/docs/recipes/self-host.md +60 -0
- package/docs/recipes/ship-and-regrade.md +72 -0
- package/docs/recipes/staging-data.md +50 -0
- package/docs/recipes/staging-environment.md +215 -0
- package/docs/recipes/upgrading-the-core.md +58 -0
- package/docs/research/cursor-competitive-analysis.md +255 -0
- package/docs/research/llm-model-agnostic-and-cheaper-grader.md +227 -0
- package/migrations/003_pms.sql +284 -0
- package/migrations/004_pms_cost_idempotency.sql +13 -0
- package/migrations/005_pms_smoke_filter.sql +44 -0
- package/migrations/006_pms_v2.sql +378 -0
- package/migrations/007_pms_v2_hierarchy_trigger.sql +59 -0
- package/migrations/008_pms_v2_migration_allocator.sql +27 -0
- package/migrations/009_pms_v2_blockers_table.sql +68 -0
- package/migrations/010_uptime.sql +29 -0
- package/migrations/011_backfill_v2_v3_done_when.sql +20 -0
- package/migrations/012_pms_v2_task_lifecycle_states.sql +82 -0
- package/migrations/013_claim_locking.sql +22 -0
- package/migrations/014_pms_task_discipline.sql +86 -0
- package/migrations/015_pms_estimation_calibration.sql +140 -0
- package/migrations/016_pms_task_grades.sql +60 -0
- package/migrations/017_version_progress_exclude_abandoned.sql +49 -0
- package/migrations/019_rename_pms_v3_to_gds_v3.sql +65 -0
- package/migrations/020_task_dependencies.sql +99 -0
- package/migrations/021_v3_renumber_and_deps.sql +224 -0
- package/migrations/022_v3_reconcile_dep_gated_status.sql +41 -0
- package/migrations/023_pms_rank.sql +30 -0
- package/migrations/025_builder_exit_status.sql +15 -0
- package/migrations/027_builders_preferred_disciplines.sql +46 -0
- package/migrations/028_tasks_parallel_safe.sql +71 -0
- package/migrations/029_rank_three_live.sql +32 -0
- package/migrations/030_vulnerability_reports.sql +61 -0
- package/migrations/031_reward_simplification.sql +57 -0
- package/migrations/032_repo_health_snapshots.sql +56 -0
- package/migrations/033_audit_log.sql +64 -0
- package/migrations/034_lifecycle_breakdown_leaf_only.sql +62 -0
- package/migrations/035_auth_token_hygiene.sql +66 -0
- package/migrations/037_builder_skill_model_prefs.sql +44 -0
- package/migrations/038_task_override_requests.sql +51 -0
- package/migrations/039_newcomer_friendly_column.sql +124 -0
- package/migrations/040_builder_karma.sql +58 -0
- package/migrations/041_kind_multipliers_and_idea_bonus.sql +42 -0
- package/migrations/042_criterion_proposal_workflow.sql +78 -0
- package/migrations/043_builder_onboarding_observability.sql +66 -0
- package/migrations/044_tasks_requires_rank.sql +97 -0
- package/migrations/045_builder_onboarding_state.sql +147 -0
- package/migrations/046_cost_log_builder_attribution.sql +42 -0
- package/migrations/054_builder_memory.sql +108 -0
- package/migrations/055_task_criteria.sql +90 -0
- package/migrations/058_peer_votes.sql +41 -0
- package/migrations/059_onboarding_pick_disciplines.sql +59 -0
- package/migrations/060_access_requests.sql +46 -0
- package/migrations/061_backfill_override_ship_attribution.sql +29 -0
- package/migrations/062_session_records.sql +34 -0
- package/migrations/063_session_records_tool_errors_idx.sql +11 -0
- package/migrations/064_grade_attempts.sql +18 -0
- package/migrations/065_bfg_principal.sql +58 -0
- package/migrations/066_live_notify_triggers.sql +69 -0
- package/migrations/067_builder_boxes.sql +117 -0
- package/migrations/067_discord_bot_foundation.sql +69 -0
- package/migrations/068_thetes_requires_rank.sql +27 -0
- package/migrations/069_builder_ssh_keys.sql +66 -0
- package/migrations/070_box_intents.sql +101 -0
- package/migrations/071_box_first_provision_approval.sql +46 -0
- package/migrations/072_onboarding_ship_three_remove_primer.sql +80 -0
- package/migrations/073_box_terminal_access.sql +46 -0
- package/migrations/075_builder_sound_prefs.sql +28 -0
- package/migrations/078_box_claude_active.sql +22 -0
- package/migrations/079_box_first_connected_at.sql +20 -0
- package/migrations/081_tasks_needs_migration.sql +34 -0
- package/migrations/084_tasks_security_sensitive.sql +24 -0
- package/migrations/085_security_engagement_docs.sql +34 -0
- package/migrations/086_rename_disciplines.sql +125 -0
- package/migrations/088_builders_anthropic_link.sql +28 -0
- package/migrations/089_builders_monthly_budget.sql +19 -0
- package/migrations/090_box_scoped_sessions.sql +38 -0
- package/migrations/091_session_token_reward.sql +44 -0
- package/migrations/093_tasks_sandbox_review.sql +22 -0
- package/migrations/102_remove_box_first_provision_approval.sql +58 -0
- package/migrations/103_search_chunks.sql +90 -0
- package/migrations/104_builder_box_blocked.sql +34 -0
- package/migrations/105_box_host_keys.sql +35 -0
- package/migrations/111_medusa_customer0_framing.sql +35 -0
- package/migrations/112_drop_track_check.sql +25 -0
- package/migrations/113_merge_lease.sql +16 -0
- package/migrations/114_cloudbongos_rename_live_strings.sql +32 -0
- package/migrations/118_currency_label_decoupling.sql +23 -0
- package/migrations/119_builder_behavior_prefs.sql +31 -0
- package/migrations/121_box_code_version.sql +37 -0
- package/migrations/122_builder_gemini_key.sql +30 -0
- package/migrations/123_cost_log_tiers.sql +33 -0
- package/migrations/124_cost_baseline.sql +45 -0
- package/migrations/125_llm_cache.sql +54 -0
- package/migrations/126_autonomy_runs.sql +33 -0
- package/migrations/143_cost_calibration.sql +63 -0
- package/migrations/145_backfill_task_requires_rank.sql +84 -0
- package/migrations/160_goal_tier.sql +88 -0
- package/migrations/163_polymorphic_dependencies.sql +187 -0
- package/migrations/164_event_sound_prefs.sql +20 -0
- package/migrations/165_task_module_key.sql +15 -0
- package/migrations/171_claims_published_head_sha.sql +24 -0
- package/migrations/174_close_orphaned_claims_on_terminal_tasks.sql +30 -0
- package/migrations/175_task_grades_diff_hash.sql +9 -0
- package/migrations/176_promotion_respects_open_blockers.sql +58 -0
- package/migrations/176_ui_discipline.sql +40 -0
- package/migrations/177_require_reward_before_workable.sql +76 -0
- package/migrations/178_reward_gate_auto_assign_revert_autopromote.sql +61 -0
- package/migrations/179_search_chunk_usefulness.sql +33 -0
- package/migrations/180_one_active_claim_per_session.sql +54 -0
- package/migrations/181_cost_log_skill_name.sql +33 -0
- package/migrations/184_claim_release_requested.sql +25 -0
- package/migrations/185_module_upstreaming_goal_wiring.sql +59 -0
- package/migrations/187_goal_sort_order.sql +30 -0
- package/migrations/187_tasks_kind_check_add_verify.sql +21 -0
- package/migrations/README.md +88 -0
- package/migrations/core_188_goal_visibility_and_membership_requests.sql +71 -0
- package/migrations/core_189_core_upgrades_ledger.sql +37 -0
- package/migrations/core_189_credit_log_task_id_index.sql +19 -0
- package/migrations/core_190_rebuild_claimable_task_views.sql +71 -0
- package/migrations/instance/018_pms_v3_planning_seed.sql +131 -0
- package/migrations/instance/080_gds_v4_planning_seed.sql +75 -0
- package/migrations/instance/110_medusa_planning_seed.sql +70 -0
- package/migrations/instance/120_bongos_v1_planning_seed.sql +69 -0
- package/migrations/instance/144_bongos_v1_module_system_criterion.sql +26 -0
- package/migrations/instance/159_bongos_v1_goal_hierarchy_criterion.sql +29 -0
- package/migrations/instance/172_v2_world_planning_seed.sql +163 -0
- package/migrations/instance/173_bongos_v1_c7_core_modularized.sql +33 -0
- package/migrations/instance/182_gdsv4_bongos_consolidation.sql +132 -0
- package/migrations/instance/183_gdsv4_carryover_themed_goals.sql +116 -0
- package/migrations/instance/186_bongos_v1_governance_planning_seed.sql +69 -0
- package/modules/autonomy/CLAUDE.md +49 -0
- package/modules/autonomy/db.js +50 -0
- package/modules/autonomy/module.json +13 -0
- package/modules/autonomy/pollers/routine-timers.js +146 -0
- package/modules/autonomy/routes/autonomy.js +37 -0
- package/modules/builder-settings/CLAUDE.md +58 -0
- package/modules/builder-settings/builder-needs.js +115 -0
- package/modules/builder-settings/db.js +168 -0
- package/modules/builder-settings/display-name.js +84 -0
- package/modules/builder-settings/event-sound-prefs.js +169 -0
- package/modules/builder-settings/interaction-prefs.js +201 -0
- package/modules/builder-settings/model-alloc-prefs.js +147 -0
- package/modules/builder-settings/module.json +10 -0
- package/modules/builder-settings/render-prefs.js +103 -0
- package/modules/builder-settings/routes/settings.js +417 -0
- package/modules/builder-settings/settings.js +52 -0
- package/modules/builder-settings/skill-prefs.js +196 -0
- package/modules/builder-settings/sound-prefs.js +178 -0
- package/modules/builder-settings/wandering-prefs.js +282 -0
- package/modules/dev-box/CLAUDE.md +38 -0
- package/modules/dev-box/box-access.js +275 -0
- package/modules/dev-box/box-credential.js +94 -0
- package/modules/dev-box/box-onboard.js +486 -0
- package/modules/dev-box/boxes.js +842 -0
- package/modules/dev-box/db.js +39 -0
- package/modules/dev-box/module.json +14 -0
- package/modules/dev-box/routes/box.js +977 -0
- package/modules/discord/CLAUDE.md +50 -0
- package/modules/discord/auth.js +54 -0
- package/modules/discord/bug-attachments.js +210 -0
- package/modules/discord/db.js +96 -0
- package/modules/discord/discord-approvals.js +145 -0
- package/modules/discord/discord-audit.js +29 -0
- package/modules/discord/discord-bot.js +545 -0
- package/modules/discord/discord-bugs.js +257 -0
- package/modules/discord/discord-channels.js +412 -0
- package/modules/discord/discord-inbound.js +147 -0
- package/modules/discord/discord-message-buffer.js +54 -0
- package/modules/discord/discord-reaction.js +186 -0
- package/modules/discord/discord-role-sync.js +318 -0
- package/modules/discord/module.json +14 -0
- package/modules/discord/pollers/discord-bot.js +19 -0
- package/modules/discord/routes/bug-attachments.js +44 -0
- package/modules/discord/routes/discord.js +102 -0
- package/modules/discord/ship-broadcast.js +78 -0
- package/modules/discord/webhook.js +74 -0
- package/modules/economy/CLAUDE.md +48 -0
- package/modules/economy/achievements.js +594 -0
- package/modules/economy/cost-classify.js +331 -0
- package/modules/economy/cost-summary-shape.js +90 -0
- package/modules/economy/cost.js +438 -0
- package/modules/economy/credits.js +430 -0
- package/modules/economy/migrations/economy_001_fix_gds_shipper_description.sql +91 -0
- package/modules/economy/module.json +10 -0
- package/modules/economy/reward.js +61 -0
- package/modules/economy/routes/cost.js +97 -0
- package/modules/economy/routes/leaderboard.js +26 -0
- package/modules/economy/routes/reward.js +42 -0
- package/modules/economy/streak.js +285 -0
- package/modules/grading/CLAUDE.md +42 -0
- package/modules/grading/db.js +39 -0
- package/modules/grading/grader-rubric.json +151 -0
- package/modules/grading/grader-workers/efficiency.js +213 -0
- package/modules/grading/grader-workers/extract-json.js +80 -0
- package/modules/grading/grader-workers/fence.js +100 -0
- package/modules/grading/grader-workers/hacker.js +239 -0
- package/modules/grading/grader-workers/index.js +183 -0
- package/modules/grading/grader-workers/narc.js +207 -0
- package/modules/grading/grader-workers/quality.js +198 -0
- package/modules/grading/grader-workers/rubric.js +20 -0
- package/modules/grading/grader-workers/worker-prompt.js +89 -0
- package/modules/grading/grader-workers/worker-verdict.js +50 -0
- package/modules/grading/grader.js +1790 -0
- package/modules/grading/module.json +12 -0
- package/modules/grading/routes/grade.js +51 -0
- package/modules/hall-ui/CLAUDE.md +61 -0
- package/modules/hall-ui/module.json +14 -0
- package/modules/hall-ui/public/atlas.html +180 -0
- package/modules/hall-ui/public/atlas.js +336 -0
- package/modules/hall-ui/public/box-panel.js +423 -0
- package/modules/hall-ui/public/brand-apply.js +117 -0
- package/modules/hall-ui/public/builders.js +3028 -0
- package/modules/hall-ui/public/chime.wav +0 -0
- package/modules/hall-ui/public/copy-on-click.js +174 -0
- package/modules/hall-ui/public/cursors/arrow.png +0 -0
- package/modules/hall-ui/public/cursors/hand-pointer.png +0 -0
- package/modules/hall-ui/public/cursors/magnifier-out.png +0 -0
- package/modules/hall-ui/public/cursors/magnifier.png +0 -0
- package/modules/hall-ui/public/diagram-viewer.css +125 -0
- package/modules/hall-ui/public/diagram-viewer.js +330 -0
- package/modules/hall-ui/public/diagrams.html +113 -0
- package/modules/hall-ui/public/dom-utils.js +212 -0
- package/modules/hall-ui/public/drachmae.html +68 -0
- package/modules/hall-ui/public/drachmae.js +136 -0
- package/modules/hall-ui/public/gate.html +143 -0
- package/modules/hall-ui/public/gate.js +228 -0
- package/modules/hall-ui/public/goals-page.js +1297 -0
- package/modules/hall-ui/public/goals.html +376 -0
- package/modules/hall-ui/public/goals.js +119 -0
- package/modules/hall-ui/public/hall-widgets.js +189 -0
- package/modules/hall-ui/public/harbor.html +167 -0
- package/modules/hall-ui/public/harbor.js +335 -0
- package/modules/hall-ui/public/index.html +116 -0
- package/modules/hall-ui/public/instances-panel.js +172 -0
- package/modules/hall-ui/public/md-reader.js +234 -0
- package/modules/hall-ui/public/modules.html +119 -0
- package/modules/hall-ui/public/modules.js +154 -0
- package/modules/hall-ui/public/new-project-wizard.js +186 -0
- package/modules/hall-ui/public/not-ready.html +48 -0
- package/modules/hall-ui/public/pair.html +119 -0
- package/modules/hall-ui/public/pair.js +132 -0
- package/modules/hall-ui/public/primer.css +404 -0
- package/modules/hall-ui/public/primer.html +85 -0
- package/modules/hall-ui/public/primer.js +641 -0
- package/modules/hall-ui/public/profile.html +85 -0
- package/modules/hall-ui/public/profile.js +236 -0
- package/modules/hall-ui/public/ranks.html +69 -0
- package/modules/hall-ui/public/ranks.js +206 -0
- package/modules/hall-ui/public/roadmap.html +209 -0
- package/modules/hall-ui/public/roadmap.js +375 -0
- package/modules/hall-ui/public/sessions.html +92 -0
- package/modules/hall-ui/public/sessions.js +222 -0
- package/modules/hall-ui/public/settings.html +640 -0
- package/modules/hall-ui/public/settings.js +1219 -0
- package/modules/hall-ui/public/shell.js +495 -0
- package/modules/hall-ui/public/style.css +1748 -0
- package/modules/hall-ui/public/task-detail.js +253 -0
- package/modules/hall-ui/public/task.html +83 -0
- package/modules/hall-ui/public/task.js +326 -0
- package/modules/hall-ui/public/watch.html +333 -0
- package/modules/hall-ui/public/watch.js +859 -0
- package/modules/hall-ui/public/work.html +469 -0
- package/modules/hall-ui/public/work.js +1292 -0
- package/modules/ideas/CLAUDE.md +37 -0
- package/modules/ideas/blockers.js +100 -0
- package/modules/ideas/inbox.js +459 -0
- package/modules/ideas/module.json +10 -0
- package/modules/ideas/routes/blockers.js +120 -0
- package/modules/ideas/routes/inbox.js +230 -0
- package/modules/lifecycle/CLAUDE.md +63 -0
- package/modules/lifecycle/conflict-resolve.js +436 -0
- package/modules/lifecycle/db.js +4970 -0
- package/modules/lifecycle/done-when.js +355 -0
- package/modules/lifecycle/github-push.js +969 -0
- package/modules/lifecycle/goal-conflicts.js +133 -0
- package/modules/lifecycle/hierarchy.js +104 -0
- package/modules/lifecycle/lifecycle.js +58 -0
- package/modules/lifecycle/merge-lock.js +261 -0
- package/modules/lifecycle/migrations/lifecycle_001_goal_first_leads.sql +28 -0
- package/modules/lifecycle/migrations/lifecycle_002_backfill_orphan_task_goals.sql +36 -0
- package/modules/lifecycle/module.json +13 -0
- package/modules/lifecycle/pollers/publish-reconciler.js +20 -0
- package/modules/lifecycle/publish-reconciler.js +418 -0
- package/modules/lifecycle/routes/analytics.js +63 -0
- package/modules/lifecycle/routes/claims.js +506 -0
- package/modules/lifecycle/routes/dependencies.js +82 -0
- package/modules/lifecycle/routes/done-when.js +136 -0
- package/modules/lifecycle/routes/gate-approvals.js +197 -0
- package/modules/lifecycle/routes/goals.js +1419 -0
- package/modules/lifecycle/routes/lifecycle.js +43 -0
- package/modules/lifecycle/routes/tasks.js +1703 -0
- package/modules/lifecycle/routes/versions.js +128 -0
- package/modules/lifecycle/ship-card.js +505 -0
- package/modules/lifecycle/ship-preflight.js +225 -0
- package/modules/lifecycle/task-classifier.js +512 -0
- package/modules/lifecycle/version-close.js +106 -0
- package/modules/memory/CLAUDE.md +40 -0
- package/modules/memory/learnings.js +275 -0
- package/modules/memory/memory.js +572 -0
- package/modules/memory/module.json +12 -0
- package/modules/memory/routes/learnings.js +90 -0
- package/modules/memory/routes/memory.js +916 -0
- package/modules/memory/routes/search.js +188 -0
- package/modules/memory/search-chunker.js +252 -0
- package/modules/memory/search.js +320 -0
- package/modules/onboarding/CLAUDE.md +55 -0
- package/modules/onboarding/approval-broadcast.js +59 -0
- package/modules/onboarding/db.js +54 -0
- package/modules/onboarding/module.json +10 -0
- package/modules/onboarding/newcomer-restock.js +212 -0
- package/modules/onboarding/onboarding-state.js +532 -0
- package/modules/onboarding/onboarding.js +508 -0
- package/modules/onboarding/port.js +63 -0
- package/modules/onboarding/routes/access-requests.js +208 -0
- package/modules/onboarding/routes/onboarding.js +54 -0
- package/modules/security/CLAUDE.md +44 -0
- package/modules/security/module.json +10 -0
- package/modules/security/routes/reports.js +251 -0
- package/modules/security/secret-scrub.js +201 -0
- package/modules/security/security.js +294 -0
- package/modules/sessions/CLAUDE.md +39 -0
- package/modules/sessions/bfg.js +357 -0
- package/modules/sessions/db.js +326 -0
- package/modules/sessions/module.json +10 -0
- package/modules/sessions/pulse.js +149 -0
- package/modules/sessions/routes/sessions.js +331 -0
- package/modules/status-ui/CLAUDE.md +47 -0
- package/modules/status-ui/module.json +14 -0
- package/modules/status-ui/public/README.md +29 -0
- package/modules/status-ui/public/cursors/arrow.png +0 -0
- package/modules/status-ui/public/cursors/hand-pointer.png +0 -0
- package/modules/status-ui/public/index.html +363 -0
- package/modules/status-ui/public/snapshots/.gitkeep +0 -0
- package/modules/status-ui/public/status.js +1375 -0
- package/modules/status-ui/public/style.css +1342 -0
- package/package-lock.json +975 -0
- package/package.json +28 -0
- package/public-docs/index.html +35 -0
- package/public-docs/redoc.standalone.js +1838 -0
- package/public-docs/redoc.standalone.js.LICENSE.txt +102 -0
- package/public-landing/buddha.png +0 -0
- package/public-landing/create.html +868 -0
- package/public-landing/index.html +168 -0
- package/scripts/bongos-mcp.js +28 -0
- package/scripts/cron/style_guide_audit.sh +134 -0
- package/scripts/discord/README.md +52 -0
- package/scripts/discord/lib.js +80 -0
- package/scripts/discord/post.js +51 -0
- package/scripts/gds/CLAUDE.md +144 -0
- package/scripts/gds/abandon.js +58 -0
- package/scripts/gds/adopt-detect.js +123 -0
- package/scripts/gds/adopt-import.js +111 -0
- package/scripts/gds/adopt-preflight.js +121 -0
- package/scripts/gds/api.js +78 -0
- package/scripts/gds/architect-audit.js +288 -0
- package/scripts/gds/art-stage.js +152 -0
- package/scripts/gds/audit-authorship.sh +243 -0
- package/scripts/gds/audit-deps.js +121 -0
- package/scripts/gds/audit-exports.js +128 -0
- package/scripts/gds/audit-replay.sh +161 -0
- package/scripts/gds/audit-ships.js +251 -0
- package/scripts/gds/autonomy-gate.js +135 -0
- package/scripts/gds/backfill-cost.js +165 -0
- package/scripts/gds/backfill-sessions.js +351 -0
- package/scripts/gds/backfill-task-rewards.js +408 -0
- package/scripts/gds/backup.js +94 -0
- package/scripts/gds/bfg-principal-token.js +65 -0
- package/scripts/gds/box-auth-check.js +160 -0
- package/scripts/gds/box-connect-lib.js +453 -0
- package/scripts/gds/box.js +1258 -0
- package/scripts/gds/build-bongos.js +94 -0
- package/scripts/gds/capture.js +123 -0
- package/scripts/gds/cf-tunnel.js +419 -0
- package/scripts/gds/ci-grade.js +82 -0
- package/scripts/gds/claim-recall.js +112 -0
- package/scripts/gds/claim.js +333 -0
- package/scripts/gds/classify-discipline.js +153 -0
- package/scripts/gds/claude-materialize.js +176 -0
- package/scripts/gds/cleanup-orphans.js +74 -0
- package/scripts/gds/cli-lib.js +518 -0
- package/scripts/gds/code.js +101 -0
- package/scripts/gds/codemod-rename-src-gds.js +145 -0
- package/scripts/gds/conductor-dispatch.js +426 -0
- package/scripts/gds/context-pack.js +228 -0
- package/scripts/gds/coreB-carve-proof.sh +716 -0
- package/scripts/gds/cost.js +47 -0
- package/scripts/gds/db-backup-nightly.sh +160 -0
- package/scripts/gds/db-backup-offsite.sh +152 -0
- package/scripts/gds/demote.js +40 -0
- package/scripts/gds/design-sync.js +62 -0
- package/scripts/gds/diagnose-achievements.js +118 -0
- package/scripts/gds/diagram-facts.js +319 -0
- package/scripts/gds/discipline-modes.json +25 -0
- package/scripts/gds/discord-channels.js +66 -0
- package/scripts/gds/do-api.js +176 -0
- package/scripts/gds/docs-entropy.js +403 -0
- package/scripts/gds/doctor.js +389 -0
- package/scripts/gds/feedback-latest.js +94 -0
- package/scripts/gds/fetch-art-key.js +106 -0
- package/scripts/gds/fetch-sound-prefs.js +88 -0
- package/scripts/gds/figma-design-sync.js +61 -0
- package/scripts/gds/fitness.js +1446 -0
- package/scripts/gds/gate-review.js +322 -0
- package/scripts/gds/gating.js +325 -0
- package/scripts/gds/gds-db-backup.service +24 -0
- package/scripts/gds/gds-db-backup.timer +20 -0
- package/scripts/gds/gds-db-offsite.service +29 -0
- package/scripts/gds/gds-db-offsite.timer +18 -0
- package/scripts/gds/gen-api-client.js +508 -0
- package/scripts/gds/gen-api-docs.js +1037 -0
- package/scripts/gds/gen-atlas.js +366 -0
- package/scripts/gds/gen-diagrams.js +608 -0
- package/scripts/gds/gen-file-map.js +196 -0
- package/scripts/gds/gen-repo-map.js +519 -0
- package/scripts/gds/gen-session-index.js +210 -0
- package/scripts/gds/git-merge-regen.js +147 -0
- package/scripts/gds/grade-smoke.js +205 -0
- package/scripts/gds/hooks/pre-push.js +169 -0
- package/scripts/gds/http-api-client.js +88 -0
- package/scripts/gds/init.js +903 -0
- package/scripts/gds/install-git-hooks.js +114 -0
- package/scripts/gds/key-card.js +213 -0
- package/scripts/gds/key-status.js +126 -0
- package/scripts/gds/land-watch.js +168 -0
- package/scripts/gds/learning-capture.js +145 -0
- package/scripts/gds/lib.sh +44 -0
- package/scripts/gds/linkify-refs.js +473 -0
- package/scripts/gds/local-preview-lib.js +159 -0
- package/scripts/gds/local-preview.js +95 -0
- package/scripts/gds/login.js +225 -0
- package/scripts/gds/main-audit.js +279 -0
- package/scripts/gds/me.js +88 -0
- package/scripts/gds/memory-map.js +174 -0
- package/scripts/gds/merge-lock.js +71 -0
- package/scripts/gds/migration-namespace.js +200 -0
- package/scripts/gds/mirror-lineage-check.js +319 -0
- package/scripts/gds/mirror-redact.js +305 -0
- package/scripts/gds/module.js +482 -0
- package/scripts/gds/newcomer-floor.config.json +13 -0
- package/scripts/gds/newcomer-floor.js +415 -0
- package/scripts/gds/newcomer-floor.templates.json +86 -0
- package/scripts/gds/newcomer-floor.test.js +235 -0
- package/scripts/gds/next-number.js +163 -0
- package/scripts/gds/oauth-secret.js +197 -0
- package/scripts/gds/onboard.js +217 -0
- package/scripts/gds/onboarding-analyze.js +226 -0
- package/scripts/gds/onboarding-config.js +178 -0
- package/scripts/gds/onboarding-ship.js +92 -0
- package/scripts/gds/package-core.js +684 -0
- package/scripts/gds/paste-token.js +131 -0
- package/scripts/gds/portability-smoke-art.sh +85 -0
- package/scripts/gds/portability-smoke-memory.sh +147 -0
- package/scripts/gds/provision.js +1324 -0
- package/scripts/gds/publish-manifest.js +307 -0
- package/scripts/gds/pulse.js +309 -0
- package/scripts/gds/push-main.js +45 -0
- package/scripts/gds/read-session-export.js +359 -0
- package/scripts/gds/reauth.js +149 -0
- package/scripts/gds/recall.js +135 -0
- package/scripts/gds/release.js +71 -0
- package/scripts/gds/render-ideas.js +173 -0
- package/scripts/gds/repo-metrics.js +363 -0
- package/scripts/gds/resolve-skill-model.js +57 -0
- package/scripts/gds/run-routine.js +197 -0
- package/scripts/gds/run-unit-tests.js +178 -0
- package/scripts/gds/sandbox-stage.js +653 -0
- package/scripts/gds/search-ingest-db.js +209 -0
- package/scripts/gds/search-ingest-md.js +225 -0
- package/scripts/gds/security-baseline-check.sh +180 -0
- package/scripts/gds/seed-adopt-tasks.js +75 -0
- package/scripts/gds/seed-api-contract-goal-tasks.js +141 -0
- package/scripts/gds/seed-bongos-app-tasks.js +294 -0
- package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +81 -0
- package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +100 -0
- package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +307 -0
- package/scripts/gds/seed-bongos-module-system-tasks.js +346 -0
- package/scripts/gds/seed-bongos-tasks.js +214 -0
- package/scripts/gds/seed-gds-v4-tasks.js +624 -0
- package/scripts/gds/seed-governance-tasks.js +340 -0
- package/scripts/gds/seed-medusa-tasks.js +440 -0
- package/scripts/gds/seed-module-upstreaming.js +219 -0
- package/scripts/gds/seed-productization-tasks.js +235 -0
- package/scripts/gds/seed-provisioning-tasks.js +83 -0
- package/scripts/gds/seed-staging.sh +104 -0
- package/scripts/gds/seed-v2-world-tasks.js +283 -0
- package/scripts/gds/seed-v3-tasks.js +1981 -0
- package/scripts/gds/session-cost.js +393 -0
- package/scripts/gds/session-digest.js +179 -0
- package/scripts/gds/session-eval.js +576 -0
- package/scripts/gds/session.js +404 -0
- package/scripts/gds/setup.js +504 -0
- package/scripts/gds/shell.js +100 -0
- package/scripts/gds/ship.js +3618 -0
- package/scripts/gds/smoke-batch-claim.sh +213 -0
- package/scripts/gds/smoke-batch-release.sh +296 -0
- package/scripts/gds/smoke-box.sh +150 -0
- package/scripts/gds/smoke-claim-consistency.sh +212 -0
- package/scripts/gds/smoke-dependencies.sh +84 -0
- package/scripts/gds/smoke-gds.js +125 -0
- package/scripts/gds/smoke-write.sh +168 -0
- package/scripts/gds/start.js +782 -0
- package/scripts/gds/status.js +365 -0
- package/scripts/gds/triage.js +366 -0
- package/scripts/gds/upgrade.js +421 -0
- package/scripts/gds/validate-design.js +254 -0
- package/scripts/gds/version-close.js +549 -0
- package/scripts/migrate.sh +183 -0
- package/scripts/migrate_cost_ledger.sh +178 -0
- package/scripts/public-mirror-export.js +291 -0
- package/scripts/render-diagrams.sh +88 -0
- package/scripts/security/dep-audit.js +276 -0
- package/scripts/setup-builder.js +274 -0
- package/scripts/setup-builder.sh +28 -0
- package/scripts/snapshots/backfill-history.mjs +292 -0
- package/scripts/snapshots/maybe-render-on-deploy.sh +66 -0
- package/scripts/snapshots/render-pre-art-eras.mjs +329 -0
- package/scripts/snapshots/render-world.mjs +322 -0
- package/scripts/status-mirror-sync.js +192 -0
- package/scripts/status-probe.mjs +185 -0
- package/server.js +212 -0
- package/src/asset-version.js +71 -0
- package/src/bongos/CLAUDE.md +64 -0
- package/src/bongos/api-errors.js +281 -0
- package/src/bongos/api-path-404.js +67 -0
- package/src/bongos/api-prefix.js +38 -0
- package/src/bongos/app-pair.js +172 -0
- package/src/bongos/auth.js +979 -0
- package/src/bongos/cascade-dispatch.js +123 -0
- package/src/bongos/db-kernel.js +252 -0
- package/src/bongos/db.js +911 -0
- package/src/bongos/goal-scope-check.js +120 -0
- package/src/bongos/hierarchy-config.js +189 -0
- package/src/bongos/live-channel.js +145 -0
- package/src/bongos/llm-cache.js +260 -0
- package/src/bongos/llm-pricing.js +220 -0
- package/src/bongos/metrics.js +286 -0
- package/src/bongos/middleware/audit.js +274 -0
- package/src/bongos/middleware/error-envelope.js +93 -0
- package/src/bongos/middleware/rate-limit.js +195 -0
- package/src/bongos/module-scope-map.js +271 -0
- package/src/bongos/optimizer.js +166 -0
- package/src/bongos/path-match.js +47 -0
- package/src/bongos/permission-path-check.js +248 -0
- package/src/bongos/pool.js +55 -0
- package/src/bongos/repo-info.js +91 -0
- package/src/bongos/route-rank-check.js +420 -0
- package/src/bongos/routes/CLAUDE.md +43 -0
- package/src/bongos/routes/_helpers.js +369 -0
- package/src/bongos/routes/audit-log.js +59 -0
- package/src/bongos/routes/auth.js +755 -0
- package/src/bongos/routes/backup.js +104 -0
- package/src/bongos/routes/builders.js +526 -0
- package/src/bongos/routes/healthz.js +16 -0
- package/src/bongos/routes/instance.js +129 -0
- package/src/bongos/routes/live.js +125 -0
- package/src/bongos/routes/llm-cache.js +119 -0
- package/src/bongos/routes/me.js +380 -0
- package/src/bongos/routes/modules.js +131 -0
- package/src/bongos/routes/optimizer.js +54 -0
- package/src/bongos/routes/public.js +476 -0
- package/src/bongos/routes/security.js +207 -0
- package/src/bongos/routes.js +166 -0
- package/src/bongos/secret-box.js +177 -0
- package/src/bongos/sensitive-surfaces.js +30 -0
- package/src/bongos/serve-internal.js +889 -0
- package/src/bongos/uptime-poller.js +90 -0
- package/src/bongos-downloads.js +70 -0
- package/src/branding.js +182 -0
- package/src/build-info.js +77 -0
- package/src/devbox-downloads.js +67 -0
- package/src/instance-config.js +200 -0
- package/src/module-api.js +366 -0
- package/src/module-loader/loader.js +268 -0
- package/src/module-loader/manifest-schema.js +140 -0
- package/src/module-loader/provenance.js +28 -0
- package/src/module-loader/semver.js +100 -0
- package/src/module-seams.js +291 -0
- package/src/modules.js +254 -0
- package/src/platform-server.js +135 -0
- package/src/ui/adapters/claude-design/index.js +333 -0
- package/src/ui/adapters/figma/index.js +328 -0
- package/tests/abandon_task.mjs +138 -0
- package/tests/achievements_reconcile.mjs +167 -0
- package/tests/adopt_detect.mjs +141 -0
- package/tests/adopt_import.mjs +132 -0
- package/tests/adopt_preflight.mjs +105 -0
- package/tests/anti_grid.mjs +89 -0
- package/tests/api_client.mjs +231 -0
- package/tests/api_docs.mjs +283 -0
- package/tests/api_error_envelope_buildcheck.mjs +56 -0
- package/tests/api_error_envelope_middleware.mjs +99 -0
- package/tests/api_error_registry.mjs +108 -0
- package/tests/api_pagination_contract.mjs +51 -0
- package/tests/api_path_404.mjs +96 -0
- package/tests/app_pair.mjs +168 -0
- package/tests/architect.mjs +140 -0
- package/tests/art_key.mjs +121 -0
- package/tests/art_stage.mjs +121 -0
- package/tests/asset_version.mjs +94 -0
- package/tests/atlas.mjs +69 -0
- package/tests/audit_deps.mjs +74 -0
- package/tests/audit_middleware.mjs +385 -0
- package/tests/auth_admission_gate.mjs +164 -0
- package/tests/auth_anthropic_identity.mjs +95 -0
- package/tests/auth_duplicate_cookie.mjs +56 -0
- package/tests/auth_error_brand.mjs +77 -0
- package/tests/auth_flow_slice1.mjs +223 -0
- package/tests/auth_inactive_builder.mjs +94 -0
- package/tests/auth_page_gate.mjs +92 -0
- package/tests/auth_session_ttl.mjs +155 -0
- package/tests/autonomous_fit_protected_paths.mjs +115 -0
- package/tests/autonomy_gate.mjs +85 -0
- package/tests/autotile_variants.mjs +256 -0
- package/tests/autotile_xverify.mjs +133 -0
- package/tests/backfill_sessions.mjs +101 -0
- package/tests/backfill_task_rewards.mjs +152 -0
- package/tests/backup_cli.mjs +104 -0
- package/tests/bfg.mjs +327 -0
- package/tests/bfg_write.mjs +423 -0
- package/tests/bongos_box_connect.mjs +89 -0
- package/tests/bongos_dispatch.mjs +74 -0
- package/tests/bongos_downloads.mjs +118 -0
- package/tests/bongos_login.mjs +34 -0
- package/tests/box_access.mjs +186 -0
- package/tests/box_auth_check.mjs +114 -0
- package/tests/box_code_staleness.mjs +116 -0
- package/tests/box_connect_e2e.mjs +196 -0
- package/tests/box_cost.mjs +70 -0
- package/tests/box_dns_repoint.mjs +151 -0
- package/tests/box_host_keys.mjs +102 -0
- package/tests/box_onboard.mjs +317 -0
- package/tests/box_scope_session.mjs +115 -0
- package/tests/box_ship_permissions.mjs +71 -0
- package/tests/box_terminal_ssrf.mjs +90 -0
- package/tests/boxes.mjs +1255 -0
- package/tests/branding.mjs +88 -0
- package/tests/bug_attachments.mjs +189 -0
- package/tests/build_info.mjs +88 -0
- package/tests/builder_needs.mjs +99 -0
- package/tests/cap_newcomer_tasks.mjs +114 -0
- package/tests/cascade-dispatch.mjs +95 -0
- package/tests/cf_tunnel.mjs +459 -0
- package/tests/claim_recall.mjs +150 -0
- package/tests/claims_bind_session.mjs +47 -0
- package/tests/claude_materialize.mjs +148 -0
- package/tests/cli_box_scope.mjs +52 -0
- package/tests/cli_lib_formatters.mjs +87 -0
- package/tests/cli_token_reissue.mjs +147 -0
- package/tests/client_bundle_route.mjs +47 -0
- package/tests/cloud_bongos_pack.mjs +85 -0
- package/tests/conductor.mjs +496 -0
- package/tests/confirm_attribution.mjs +156 -0
- package/tests/conflict_resolve.mjs +462 -0
- package/tests/context_pack.mjs +240 -0
- package/tests/cost.mjs +94 -0
- package/tests/cost_audit.mjs +122 -0
- package/tests/cost_budget_status.mjs +78 -0
- package/tests/cost_reconcile.mjs +102 -0
- package/tests/cost_summary_shape.mjs +94 -0
- package/tests/credit_grant.mjs +376 -0
- package/tests/criterion_progress.mjs +220 -0
- package/tests/criterion_proposal.mjs +109 -0
- package/tests/criterion_ref_parse.mjs +53 -0
- package/tests/currency_label.mjs +119 -0
- package/tests/day_cycle.mjs +197 -0
- package/tests/dependencies_migration.mjs +77 -0
- package/tests/dependencies_polymorphic.mjs +212 -0
- package/tests/deploy_instance.mjs +78 -0
- package/tests/devbox_downloads.mjs +122 -0
- package/tests/diff_derived_signals.mjs +115 -0
- package/tests/discord_approvals.mjs +174 -0
- package/tests/discord_autojoin.mjs +158 -0
- package/tests/discord_bot.mjs +94 -0
- package/tests/discord_bugs.mjs +297 -0
- package/tests/discord_channels.mjs +337 -0
- package/tests/discord_foundation.mjs +76 -0
- package/tests/discord_inbound.mjs +190 -0
- package/tests/discord_message_buffer.mjs +87 -0
- package/tests/discord_oauth.mjs +55 -0
- package/tests/discord_reaction.mjs +170 -0
- package/tests/discord_role_sync.mjs +151 -0
- package/tests/display_name.mjs +123 -0
- package/tests/dns_preflight.mjs +74 -0
- package/tests/event_sound_prefs.mjs +194 -0
- package/tests/eviction_policy.mjs +279 -0
- package/tests/figma_adapter.mjs +199 -0
- package/tests/file_map.mjs +91 -0
- package/tests/first_admin_bootstrap.mjs +40 -0
- package/tests/fitness.mjs +435 -0
- package/tests/fitness_two_root.mjs +104 -0
- package/tests/fixtures/session-506-digest.json +34 -0
- package/tests/gate_approvals.mjs +451 -0
- package/tests/gate_review.mjs +152 -0
- package/tests/git_merge_regen.mjs +151 -0
- package/tests/github_push_ancestry.mjs +119 -0
- package/tests/github_push_land_proof.mjs +127 -0
- package/tests/github_push_merge_driver.mjs +175 -0
- package/tests/goal_abuse_matrix.mjs +187 -0
- package/tests/goal_achievement.mjs +146 -0
- package/tests/goal_conflicts.mjs +305 -0
- package/tests/goal_dependencies_read.mjs +73 -0
- package/tests/goal_member_roles.mjs +420 -0
- package/tests/goal_membership_requests.mjs +332 -0
- package/tests/goal_routes.mjs +203 -0
- package/tests/goal_scope_check.mjs +167 -0
- package/tests/goal_tier.mjs +312 -0
- package/tests/goal_wall_proof.mjs +112 -0
- package/tests/grade_attempts.mjs +73 -0
- package/tests/grade_attribution.mjs +117 -0
- package/tests/grade_diff_hash.mjs +191 -0
- package/tests/grade_server_authoritative.mjs +305 -0
- package/tests/grade_unavailable_display.mjs +66 -0
- package/tests/grader.mjs +1960 -0
- package/tests/grader_bypass.mjs +57 -0
- package/tests/grader_panel.mjs +252 -0
- package/tests/grader_prompt_fencing.mjs +192 -0
- package/tests/helpers.mjs +52 -0
- package/tests/hierarchy-config.mjs +81 -0
- package/tests/init.mjs +463 -0
- package/tests/instance_config.mjs +76 -0
- package/tests/instance_manifest.mjs +110 -0
- package/tests/interaction_prefs.mjs +72 -0
- package/tests/key-card.mjs +110 -0
- package/tests/key-status.mjs +45 -0
- package/tests/land_watch.mjs +115 -0
- package/tests/lifecycle-card.mjs +145 -0
- package/tests/lifecycle_breakdown_view.mjs +236 -0
- package/tests/linkify_refs.mjs +264 -0
- package/tests/live_channel.mjs +128 -0
- package/tests/live_sse.mjs +122 -0
- package/tests/llm-cache-route.mjs +110 -0
- package/tests/llm-cache.mjs +140 -0
- package/tests/llm-pricing.mjs +152 -0
- package/tests/local_preview.mjs +136 -0
- package/tests/main_audit.mjs +137 -0
- package/tests/memory_isolation.mjs +431 -0
- package/tests/memory_map.mjs +107 -0
- package/tests/memory_pull.mjs +429 -0
- package/tests/merge_lease.mjs +100 -0
- package/tests/merge_lock.mjs +312 -0
- package/tests/metrics.mjs +147 -0
- package/tests/migration_allocation.mjs +146 -0
- package/tests/migration_namespace.mjs +185 -0
- package/tests/migrations_fresh_replay_guard.mjs +38 -0
- package/tests/mirror_lineage_fulltree.mjs +45 -0
- package/tests/mirror_lineage_proof.mjs +72 -0
- package/tests/mirror_redact.mjs +193 -0
- package/tests/model_alloc_prefs.mjs +63 -0
- package/tests/module-scope-map.mjs +88 -0
- package/tests/module_api.mjs +110 -0
- package/tests/module_cli.mjs +292 -0
- package/tests/module_contributions.mjs +148 -0
- package/tests/module_loader.mjs +286 -0
- package/tests/module_manifest.mjs +194 -0
- package/tests/module_owned_tests.mjs +105 -0
- package/tests/module_provenance.mjs +34 -0
- package/tests/module_route_rank.mjs +147 -0
- package/tests/module_seams.mjs +68 -0
- package/tests/modules.mjs +156 -0
- package/tests/modules_route.mjs +38 -0
- package/tests/newcomer_floor.mjs +17 -0
- package/tests/newcomer_restock.mjs +80 -0
- package/tests/next_number.mjs +154 -0
- package/tests/oauth_secret.mjs +60 -0
- package/tests/onboard.mjs +70 -0
- package/tests/onboarding_gate.mjs +267 -0
- package/tests/onboarding_observability.mjs +344 -0
- package/tests/onboarding_route_signals.mjs +175 -0
- package/tests/onboarding_state.mjs +346 -0
- package/tests/one_active_claim_per_session.mjs +111 -0
- package/tests/orphaned_claim_ship.mjs +135 -0
- package/tests/override_attribution.mjs +142 -0
- package/tests/override_request_ownership.mjs +235 -0
- package/tests/package_core.mjs +435 -0
- package/tests/parallel-load.mjs +402 -0
- package/tests/path_match.mjs +62 -0
- package/tests/permission_path.mjs +151 -0
- package/tests/platform_boot.mjs +167 -0
- package/tests/pre_compact.mjs +60 -0
- package/tests/preview_server.mjs +127 -0
- package/tests/profile_route.mjs +197 -0
- package/tests/provision.mjs +805 -0
- package/tests/provisioning_github_app_routes.mjs +98 -0
- package/tests/public_mirror_export.mjs +124 -0
- package/tests/public_task_resolver.mjs +112 -0
- package/tests/publish_branch_route.mjs +422 -0
- package/tests/publish_manifest.mjs +184 -0
- package/tests/publish_reconciler.mjs +728 -0
- package/tests/rank_gate.mjs +463 -0
- package/tests/rate_limit_public.mjs +217 -0
- package/tests/read_session_export.mjs +89 -0
- package/tests/recall_cli.mjs +82 -0
- package/tests/recall_hints.mjs +119 -0
- package/tests/recent_shipped_window.mjs +80 -0
- package/tests/regrade_eligibility.mjs +202 -0
- package/tests/render_prefs.mjs +122 -0
- package/tests/repo_map.mjs +92 -0
- package/tests/reward_gate.mjs +284 -0
- package/tests/route_rank_check.mjs +243 -0
- package/tests/route_validation.mjs +490 -0
- package/tests/routine_timers.mjs +72 -0
- package/tests/rubric_fixtures.mjs +140 -0
- package/tests/run_routine.mjs +69 -0
- package/tests/sandbox_stage.mjs +582 -0
- package/tests/scrubber_corpus.mjs +257 -0
- package/tests/search_chunker.mjs +209 -0
- package/tests/search_ingest.mjs +96 -0
- package/tests/search_ingest_db.mjs +88 -0
- package/tests/search_isolation.mjs +204 -0
- package/tests/search_route.mjs +95 -0
- package/tests/secret_box.mjs +189 -0
- package/tests/security_docs.mjs +186 -0
- package/tests/security_route.mjs +108 -0
- package/tests/served_paths_shipped.mjs +118 -0
- package/tests/session-cards.mjs +142 -0
- package/tests/session_506_regression.mjs +69 -0
- package/tests/session_caps.mjs +238 -0
- package/tests/session_cost.mjs +133 -0
- package/tests/session_digest.mjs +73 -0
- package/tests/session_eval.mjs +386 -0
- package/tests/session_index.mjs +105 -0
- package/tests/session_records.mjs +369 -0
- package/tests/session_search.mjs +78 -0
- package/tests/session_start_freshness.mjs +123 -0
- package/tests/setup_smoke.mjs +154 -0
- package/tests/ship_autolinkify.mjs +60 -0
- package/tests/ship_automerge_injection.mjs +174 -0
- package/tests/ship_broadcast_routing.mjs +125 -0
- package/tests/ship_broadcast_server.mjs +175 -0
- package/tests/ship_card.mjs +280 -0
- package/tests/ship_ci_deploy.mjs +374 -0
- package/tests/ship_preflight.mjs +368 -0
- package/tests/ship_premerge.mjs +75 -0
- package/tests/ship_resume.mjs +129 -0
- package/tests/ship_upload_skip.mjs +89 -0
- package/tests/ship_zero_commit.mjs +60 -0
- package/tests/single_host_hall.mjs +98 -0
- package/tests/skill_prefs.mjs +150 -0
- package/tests/smoke_preflight.mjs +66 -0
- package/tests/snapshot_picker.mjs +233 -0
- package/tests/sound_prefs.mjs +198 -0
- package/tests/sprite_facing.mjs +35 -0
- package/tests/status-probe.mjs +89 -0
- package/tests/status_backfill.mjs +94 -0
- package/tests/stop_refcheck.mjs +127 -0
- package/tests/streak.mjs +175 -0
- package/tests/subdomain_auth.mjs +58 -0
- package/tests/task_classifier_vocab.mjs +41 -0
- package/tests/task_create_idempotency.mjs +96 -0
- package/tests/task_goal_link.mjs +93 -0
- package/tests/task_ownership_gate.mjs +125 -0
- package/tests/terrain_picker.mjs +298 -0
- package/tests/touches_overlap.mjs +75 -0
- package/tests/triage_development.mjs +140 -0
- package/tests/turn_in_place.mjs +280 -0
- package/tests/upgrade.mjs +357 -0
- package/tests/verify_task_guard.mjs +64 -0
- package/tests/version_close.mjs +76 -0
- package/tests/versions_route.mjs +93 -0
- package/tests/walkability.mjs +188 -0
- package/tests/wandering_prefs.mjs +176 -0
- package/tests/worktree_disambiguation.mjs +105 -0
- package/tests/worktree_guard.mjs +90 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Recipe — per-builder dev box lifecycle (provision · auto-suspend · reclaim)
|
|
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`.
|
|
4
|
+
|
|
5
|
+
## The shape
|
|
6
|
+
|
|
7
|
+
Each builder gets **one** box (ADR 0031 §2). Its lifecycle is a small state machine tracked in the `builder_boxes` table:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
idle > BOX_IDLE_MINUTES (auto, every 15m) task 804:
|
|
11
|
+
none ─provision─▶ active ──────────────────────────────▶ destroyed destroys
|
|
12
|
+
▲ │ ▲ droplet
|
|
13
|
+
wake(manual) │ park(manual) │ + snapshot
|
|
14
|
+
│ ▼ │
|
|
15
|
+
parked ── parked > BOX_DORMANT_DAYS ──────┘
|
|
16
|
+
(auto, daily)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- **provision** — create + boot a droplet running the [#596](https://example.com/builders#/task/596) devcontainer. **Rank-gated.**
|
|
20
|
+
- **idle deprovision** (auto, every 15 min) — when an `active` box is idle > `BOX_IDLE_MINUTES`, **destroy the droplet AND its snapshot** ([#804](https://example.com/builders#/task/804)). Compute billing stops; nothing is kept. **Not reversible** — the next connect re-provisions a fresh box, and any uncommitted work on the old box is lost (spike [#837](https://example.com/builders#/task/837)).
|
|
21
|
+
- **park** (manual Archon CLI only) — snapshot the droplet then **destroy** it. A powered-off DO droplet still bills; only a destroyed one stops. The snapshot (~$0.30/mo) is the cheap residual you can `wake` from. **No longer automatic** — the idle sweep deprovisions instead of parking ([#804](https://example.com/builders#/task/804)).
|
|
22
|
+
- **wake** (manual, on demand) — recreate the droplet from its snapshot. New IP; the `hostname` is repointed via `BOX_DNS_HOOK`.
|
|
23
|
+
- **dormant reclaim** (auto, daily) — destroy the snapshot of a box `parked` > `BOX_DORMANT_DAYS`. Since idle no longer parks, this only catches boxes an Archon **manually** parked.
|
|
24
|
+
|
|
25
|
+
### How "idle" is detected
|
|
26
|
+
|
|
27
|
+
The idle sweep **deprovisions** a box when its `last_activity_at` (else `active_since`) is older than `BOX_IDLE_MINUTES` **and** `claude_active` is not true. Both signals are set by **`infra/box-heartbeat.sh`**, which runs **inside the box** every ~5 min and POSTs `/api/gds/box/heartbeat` *only while the box is in use* — an interactive login session, an established SSH connection, an **open browser terminal** (ttyd websocket, [#1161](https://example.com/builders#/task/1161)), or non-trivial CPU load. Silence = the sweep is free to destroy it.
|
|
28
|
+
|
|
29
|
+
> ⚠️ **The idle sweep's correctness depends on the box-side heartbeat reaching the server.** If it isn't pinging — no GDS token on the box yet, a pre-[#1161](https://example.com/builders#/task/1161) script that can't see a browser terminal, or the cron not installed — `last_activity_at` never advances and the sweep falls back to `active_since`, i.e. it measures **uptime**, not activity, and will **destroy** a box someone is actively using. Because the idle path is now a full deprovision (no park to wake from), that wrongly-reaped box also loses uncommitted work (spike [#837](https://example.com/builders#/task/837)).
|
|
30
|
+
>
|
|
31
|
+
> **Live mitigation (2026-06-16):** `BOX_IDLE_MINUTES` is raised to **120** in `/etc/example/box.env` as a soak margin until [#1161](https://example.com/builders#/task/1161)'s browser-terminal heartbeat is verified on a newcomer box; lower it back toward the 10-min default once that's proven.
|
|
32
|
+
|
|
33
|
+
Two sweeps automate the middle (both mirror `stale-claim-release` — dry-run first, idempotent, capped):
|
|
34
|
+
|
|
35
|
+
| Sweep | Cadence | What it does | Threshold |
|
|
36
|
+
|---|---|---|---|
|
|
37
|
+
| `box-idle-suspend` | every 15 min | **deprovision** `active` boxes with no activity — destroy droplet **and** snapshot ([#804](https://example.com/builders#/task/804)); not a park | `BOX_IDLE_MINUTES` (default 10; **currently 120 live**) |
|
|
38
|
+
| `box-dormant-reclaim` | daily | destroy the snapshot of long-`parked` boxes (pings builder). Since idle no longer parks, only catches **manual** Archon parks | `BOX_DORMANT_DAYS` (14) |
|
|
39
|
+
|
|
40
|
+
## Why a self-built sweep (not Coder)
|
|
41
|
+
|
|
42
|
+
ADR 0031 §9.3, resolved 2026-06-04: Coder needs an always-on control-plane droplet (~$12–24/mo fixed) + ops; a self-built sweep has ≈ $0 fixed cost and rides the existing sweep/timer pattern. See the ADR for the full rationale. (The original sweep snapshotted-and-parked idle boxes; [#804](https://example.com/builders#/task/804) simplified the idle path to a direct deprovision — the snapshot/wake machinery now serves only the manual `park`/`wake` commands.)
|
|
43
|
+
|
|
44
|
+
## The CLI — `node scripts/gds/box.js`
|
|
45
|
+
|
|
46
|
+
**Dry-run is the default. Nothing touches DigitalOcean or the DB without `--apply`.** Run any command once without `--apply` to see the plan.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
node scripts/gds/box.js status # roster + cost (read-only)
|
|
50
|
+
node scripts/gds/box.js provision <login|id> # plan a provision
|
|
51
|
+
node scripts/gds/box.js provision <login|id> --apply
|
|
52
|
+
node scripts/gds/box.js park <login|id> --apply
|
|
53
|
+
node scripts/gds/box.js wake <login|id> --apply
|
|
54
|
+
node scripts/gds/box.js deprovision <login|id> --apply
|
|
55
|
+
node scripts/gds/box.js sweep-idle # plan; add --apply to act
|
|
56
|
+
node scripts/gds/box.js sweep-dormant # plan; add --apply to act
|
|
57
|
+
node scripts/gds/box.js reconcile-drift # DO⇄DB drift; add --apply to act
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`<builder>` is a GitHub login or a numeric builder id.
|
|
61
|
+
|
|
62
|
+
### Drift reconcile — `reconcile-drift` (task [#1289](https://example.com/builders#/task/1289), [ADR 0071](../adr/<redacted>.md))
|
|
63
|
+
|
|
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
|
+
|
|
66
|
+
`reconcile-drift` is the backstop. It lists the real fleet droplets (a live read — needs `DO_API_TOKEN`, present in `box.env`) and reconciles against the GDS rows **both ways**:
|
|
67
|
+
|
|
68
|
+
- **Zombie** — a droplet no live box row claims → force-delete the droplet + its tunnel/DNS.
|
|
69
|
+
- **Ghost** — a live row whose `droplet_id` vanished from DO → mark it `destroyed`.
|
|
70
|
+
|
|
71
|
+
A droplet younger than 30 min is never killed (it may be a provision in flight). It runs hourly on the control plane via `box-drift-reconcile.timer` (see *Going live* below). Run it by hand (dry-run first) any time you suspect drift:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
node scripts/gds/box.js reconcile-drift # show the plan
|
|
75
|
+
node scripts/gds/box.js reconcile-drift --apply # repair
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Rank gate (ADR 0016 trust boundary)
|
|
79
|
+
|
|
80
|
+
`provision` reads the builder's **live DB rank** (the same value `requireRank` reads — uncacheable, server-side) and refuses below `BOX_PROVISION_MIN_RANK`. Default floor is `xenos`: per ADR 0031 §5(b) even an onboarded newcomer gets an org-funded **starter** box. The **scope** differs by rank, not the right to a box:
|
|
81
|
+
|
|
82
|
+
- **xenos → `scope='starter'`** — the box is tagged for the scoped surface [#600](https://example.com/builders#/task/600) will enforce.
|
|
83
|
+
- **metic / archon → `scope='full'`** — full private-repo access (also [#600](https://example.com/builders#/task/600)).
|
|
84
|
+
|
|
85
|
+
Raise the floor (e.g. boxes for Metic+ only) by setting `BOX_PROVISION_MIN_RANK=metic`.
|
|
86
|
+
|
|
87
|
+
## Config (environment)
|
|
88
|
+
|
|
89
|
+
Put these in `/etc/example/box.env` (chmod 600 — **secrets never go in the repo**, [ADR 0022](../adr/0022-secrets-policy.md)). The systemd units load it via `EnvironmentFile=`.
|
|
90
|
+
|
|
91
|
+
| Var | Default | Meaning |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| `DO_API_TOKEN` | — | DigitalOcean API token. **Required for `--apply`**; absent ⇒ live calls throw clearly. |
|
|
94
|
+
| `BOX_PROVISION_MIN_RANK` | `xenos` | provisioning rank floor |
|
|
95
|
+
| `BOX_REGION` | `nyc3` | droplet region |
|
|
96
|
+
| `BOX_SIZE` | `s-2vcpu-4gb` | droplet size (4 GB floor — the devcontainer sets a 4 GB Node heap) |
|
|
97
|
+
| `BOX_BASE_IMAGE` | `ubuntu-24-04-x64` | first-provision base image (cloud-init installs Docker + the devcontainer) |
|
|
98
|
+
| `BOX_IDLE_MINUTES` | `10` | idle-**deprovision** threshold (minutes). **Currently overridden to `120` live** as a soak margin — see "How idle is detected". |
|
|
99
|
+
| `BOX_DORMANT_DAYS` | `14` | dormant-reclaim threshold |
|
|
100
|
+
| `BOX_SSH_KEY_IDS` | — | comma-list of DO SSH key ids/fingerprints to inject (so you can SSH in) |
|
|
101
|
+
| `BOX_REPO_URL` | — | git URL the cloud-init clones into `/workspace`. The scoped **credential** is [#600](https://example.com/builders#/task/600); no identity is hardcoded. |
|
|
102
|
+
| `BOX_DNS_HOOK` | — | optional shell command run on provision/wake with `BOX_HOSTNAME`/`BOX_IP` in env, to repoint the per-builder hostname |
|
|
103
|
+
| `BOX_DNS_ZONE` | `dev.example.com` | the per-builder hostname zone (`box-<login>.<zone>`) |
|
|
104
|
+
| `BOX_TAG` | `otb-builder-box` | DO tag applied to every box droplet |
|
|
105
|
+
|
|
106
|
+
## Cost (Criterion C1 / cost)
|
|
107
|
+
|
|
108
|
+
A box accrues compute cost **only while `active`**. At park/deprovision the CLI computes `active hours × the size's hourly rate` and writes it to both the `box_events` ledger and `cost_log` (category `compute`, builder-attributed) — so the public status dashboard's per-builder split sees real box spend. `box.js status` prints the active monthly run-rate + total spent. The **rebill to drachmae/earnings** (org-funded starter → self-fund) is a separate task, [#602](https://example.com/builders#/task/602).
|
|
109
|
+
|
|
110
|
+
## Going live (one-time operator steps)
|
|
111
|
+
|
|
112
|
+
These spend money and are intentionally manual.
|
|
113
|
+
|
|
114
|
+
> **Hardware-verified end-to-end (2026-06-06, [#720](https://example.com/builders#/task/720)).** The lane now boots a *usable* box: auto-provision by draining the intent queue (`box.js run-intents` / `box-intent-runner.timer`), wake-on-connect from snapshot via `POST /box/ensure`, and SSH connect with the injected key. **`box-intent-runner.timer` is installed + enabled on the control plane as of [#720](https://example.com/builders#/task/720).** That run also found **[#724](https://example.com/builders#/task/724)**: the cloud-init template carried non-ASCII characters (em-dash, §) that cloud-init's strict YAML loader silently rejected — so *every* box before [#724](https://example.com/builders#/task/724) (including the [#699](https://example.com/builders#/task/699) lifecycle test) booted as a bare Ubuntu image with no devcontainer. **Keep `infra/builder-box-cloud-init.yaml` ASCII-only** (scan with `LC_ALL=C grep -nP '[^\x00-\x7f]' infra/builder-box-cloud-init.yaml`) and assert `cloud-init status` is `done` (not `degraded`) on the box after any provision change. Still deferred to **[#725](https://example.com/builders#/task/725)** (needs `BOX_SOURCE_*` GitHub tokens): the rank-gated source-fetch ([#600](https://example.com/builders#/task/600)) leg, full RC pairing, the fresh-account dry-run, plus the `box-source-fetch.sh` `HOME`-unbound fix. The idle/dormant sweeps are now LIVE — wired on the control plane 2026-06-15 ([#1101](https://example.com/builders#/task/1101)); they depend on the box-heartbeat, which needs the source clone (leg 1).
|
|
115
|
+
|
|
116
|
+
> **Source + DNS verified (2026-06-06, [#725](https://example.com/builders#/task/725)).** **Leg 1 ✅** — `BOX_SOURCE_*` is wired on the **web** tier via `/etc/example/web-source.env` (a systemd drop-in `EnvironmentFile`, deliberately separate from `box.env` so the internet-facing web process never holds `DO_API_TOKEN`); `GET /box/source-access` issues a rank-scoped credential and the box clones into `/workspace` with the credential **scrubbed from `.git/config`**. **[#599](https://example.com/builders#/task/599) hostname cutover ✅ DONE** — in `box.env`: `CLOUDFLARE_API_TOKEN` (Zone:DNS:Edit, IP-locked to the droplet) + `BOX_DNS_HOOK=/home/lars/example/infra/box-dns-cloudflare.sh`; `box.js` runs it on every provision/wake so `box-<login>.dev.example.com` tracks the box IP (verified live: a park→wake gave a new IP and DNS auto-updated with no manual step; SSH via the hostname works). **The hook forces `curl -4`** — the control-plane droplet has IPv6 egress that would otherwise bypass an IPv4 token allow-list. Gotcha: a Cloudflare token IP-locked to the droplet's IPv4 returns "Invalid API Token" from `/user/tokens/verify` (and from any IPv6-sourced call) — test against the real op (`GET /zones`), not the verify endpoint, especially for account-scoped `cfat_`-prefixed tokens. Still partial: leg 5 (RC pairing needs a `claude` login on the box) + leg 6 (fresh-account needs a 2nd GitHub account). **DNS reliability hardened ([#1180](https://example.com/builders#/task/1180), 2026-06-16):** the hook now RETRIES every Cloudflare call with backoff — a transient auth blip during the provision call-burst used to leave the A record pinned at the prior (now-dead) IP while reporting a misleading "zone not found"; it now self-heals and, on a genuine failure, surfaces the real CF error code. `runDnsHook` no longer swallows a hook failure (it records a `box_events` `error` row and flags the box DNS-stale instead of logging a clean "✓ active"). The browser terminal is independent of this record (it rides the outbound tunnel). _(Root cause: @kingaonline's Claude Desktop hit "handshake timeout" SSHing to a hostname pinned at a dead IP.)_ **DNS teardown refined ([idea 309](https://example.com/builders#/idea/309) → task [#1234](https://example.com/builders#/task/1234)):** on deprovision `deprovisionOne` **repoints** the A record to a non-routable blackhole sentinel (`192.0.2.1`, TEST-NET-1 / RFC 5737) via `runDnsHookBlackhole` instead of **deleting** it. 1180 originally deleted the record on teardown so it couldn't dangle at a recycled DO IP — but delete-then-recreate across a reap→rebuild opened a window where the name returned `NXDOMAIN`, which resolvers negative-cache for the zone's SOA neg-TTL (~30 min on the Cloudflare `example.com` zone, not builder-editable); a client that queried mid-gap (e.g. an open Claude Desktop) then kept getting `ENOTFOUND` long after the box was back. A record that always resolves (to a guaranteed-dead sentinel) has nothing to negative-cache, yet still can't dangle at a recycled IP; the next provision/wake `PUT`s it straight to the live IP at the 60s record TTL, no gap. (Lowering the neg-TTL — the other lever floated in idea 309 — isn't used: Cloudflare's per-zone SOA neg-TTL isn't builder/API-editable, and the repoint makes it moot.) The hook's `BOX_DNS_DELETE=1` / `--delete` mode is retained for **manual** operator cleanup.
|
|
117
|
+
|
|
118
|
+
1. **Token + config.** Create `/etc/example/box.env` (chmod 600) with at least `DO_API_TOKEN` and `BOX_SSH_KEY_IDS`. Apply migration 067 on the prod DB (`bash scripts/migrate.sh`).
|
|
119
|
+
> **`DO_API_TOKEN` must carry `tag:create` scope.** The first 2026-06-04 hardware run failed with `DO POST /droplets … missing the required permission tag:create` (the CLI applies `BOX_TAG` to every box). Use a **Full-Access** token, or a custom token that includes **tag write** alongside droplet + snapshot read/write.
|
|
120
|
+
> **Hardware-verified (2026-06-04, [#699](https://example.com/builders#/task/699)):** the full `provision → park → wake → deprovision` cycle has run on real DigitalOcean droplets (`box_events` ledger). Still unverified on hardware: the rank-gated source-fetch ([#600](https://example.com/builders#/task/600)) leg and the live Claude Desktop connect.
|
|
121
|
+
2. **Try one box in dry-run, then live.**
|
|
122
|
+
```bash
|
|
123
|
+
node scripts/gds/box.js provision <login> # read the plan
|
|
124
|
+
node scripts/gds/box.js provision <login> --apply # create it
|
|
125
|
+
node scripts/gds/box.js status
|
|
126
|
+
```
|
|
127
|
+
SSH in (DO assigns the IP shown), confirm the devcontainer came up, then `park`/`wake` it once to confirm the snapshot round-trips.
|
|
128
|
+
3. **Wire the box-side heartbeat** (so the idle sweep measures activity, not uptime). On the box, schedule `infra/box-heartbeat.sh` every ~5 min — e.g. `*/5 * * * * /workspace/infra/box-heartbeat.sh >> /tmp/box-heartbeat.log 2>&1` (or hang it off [#599](https://example.com/builders#/task/599)'s box service supervisor). Confirm `GET /api/gds/box/me` shows `last_activity_at` advancing while you're connected.
|
|
129
|
+
4. **Wire the sweeps + the onboarding intent runner** (systemd units ship in `infra/`):
|
|
130
|
+
```bash
|
|
131
|
+
sudo cp infra/box-idle-suspend.{service,timer} infra/box-dormant-reclaim.{service,timer} infra/box-intent-runner.{service,timer} infra/box-drift-reconcile.{service,timer} /etc/systemd/system/
|
|
132
|
+
sudo systemctl daemon-reload
|
|
133
|
+
sudo systemctl enable --now box-idle-suspend.timer box-dormant-reclaim.timer box-intent-runner.timer box-drift-reconcile.timer
|
|
134
|
+
systemctl list-timers 'box-*' # confirm next-run times
|
|
135
|
+
```
|
|
136
|
+
Tail `journalctl -u box-idle-suspend.service` for a day to confirm boxes park + wake cleanly.
|
|
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.
|
|
140
|
+
|
|
141
|
+
## Boundaries (other ADR-0031 tasks)
|
|
142
|
+
|
|
143
|
+
- **[#596](https://example.com/builders#/task/596)** (done) — the devcontainer (box-as-code) this provisions.
|
|
144
|
+
- **[#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.)
|
|
145
|
+
- **[#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.
|
|
146
|
+
- **[#602](https://example.com/builders#/task/602)** — cost passthrough (org-funded starter → self-fund via the `costs`/drachmae system). [#598](https://example.com/builders#/task/598) logs the cost; [#602](https://example.com/builders#/task/602) rebills it.
|
|
147
|
+
|
|
148
|
+
## Safety properties
|
|
149
|
+
|
|
150
|
+
- **No HTTP provisioning — the web process never touches the DO API.** Lifecycle mutations (provision/park/wake/deprovision) run only on the control-plane CLI; `DO_API_TOKEN` lives only in `/etc/example/box.env`, never the web tier. The API surface is read (`GET /box/me`, `GET /boxes`, `GET /box/terminal`) plus own-scoped writes that **record a request, not an action**: `POST /box/heartbeat` and — [#701](https://example.com/builders#/task/701) — `POST /box/ensure`, which only writes a `box_intents` row. The control-plane `box.js run-intents` is what actually calls DO. A stolen builder token can, at most, queue a provision/wake of **its own** box (rank-gated, one open intent max) — it can never create, destroy, or reach another builder's infrastructure.
|
|
151
|
+
- **Dry-run default + token-required-for-live.** You cannot accidentally spend money; a live call without `DO_API_TOKEN` throws rather than silently no-op'ing.
|
|
152
|
+
- **Audited.** Every transition writes a `box_events` row (`provision`/`park`/`wake`/`deprovision`/`cost`/`error`) with the actor (`cli:<login>` / `sweep:idle` / `sweep:dormant`).
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Recipe: Claude Design loop
|
|
2
|
+
|
|
3
|
+
> End-to-end guide for the repo ↔ Claude Design sync cycle.
|
|
4
|
+
> ADR: [ADR 0081](../adr/<redacted>.md).
|
|
5
|
+
> Adapter: `src/ui/adapters/claude-design/index.js`.
|
|
6
|
+
> CLI: `scripts/gds/design-sync.js`.
|
|
7
|
+
> Skill: `.claude/skills/design-sync/SKILL.md`.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## When to use this
|
|
12
|
+
|
|
13
|
+
- Starting a UI sprint and want Claude Design to prototype from real tokens, not approximations.
|
|
14
|
+
- Tokens or surfaces changed and the Claude Design project is stale.
|
|
15
|
+
- A Claude Design prototype is done and you want to land the generated code as a GDS task.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
- **Rank: Metic+** (design-sync routes are Metic-gated server-side).
|
|
22
|
+
- **Claimed GDS task** — use this for the handoff step. If you're just exporting, no claim is required; a claim is required when you `export()` and commit the generated code.
|
|
23
|
+
- **DesignSync MCP** — the `mcp__DesignSync__*` tools must be available in your session.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 1. Build the token bundle
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
node scripts/gds/design-sync.js
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Output (JSON on stdout):
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"bundlePath": "/tmp/otb-design-bundle-XXXXX",
|
|
38
|
+
"files": [
|
|
39
|
+
"tokens/colors.html",
|
|
40
|
+
"tokens/typography.html",
|
|
41
|
+
"tokens/spacing.html",
|
|
42
|
+
"tokens/radii.html",
|
|
43
|
+
"tokens.css",
|
|
44
|
+
"tokens.json",
|
|
45
|
+
"surfaces.json"
|
|
46
|
+
],
|
|
47
|
+
"surfaceIds": ["hall-ui", "status-ui"],
|
|
48
|
+
"summary": "bundle → /tmp/otb-design-bundle-XXXXX · 2 surface(s) · tokens: colors, typography, spacing, radii"
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**To scope to one surface:**
|
|
53
|
+
```bash
|
|
54
|
+
node scripts/gds/design-sync.js --surface hall-ui
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 2. Push to Claude Design
|
|
60
|
+
|
|
61
|
+
Use the DesignSync MCP tool in your Claude Code session:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
list_projects → pick the OTB project (or create "Off the Boats — Design System")
|
|
65
|
+
finalize_plan → stage all files from manifest.files, rooted at bundlePath
|
|
66
|
+
write_files → push the bundle
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
After the push:
|
|
70
|
+
- Token preview cards appear under **Design System** → **Tokens** (colors / typography / spacing / radii).
|
|
71
|
+
- `tokens.css` is available for prototype stylesheets as `--dt-<group>-<key>` CSS vars.
|
|
72
|
+
- `surfaces.json` tells Claude Design which surfaces exist.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## 3. Prototype in Claude Design
|
|
77
|
+
|
|
78
|
+
Claude Design can now reference the token cards. Typical workflow:
|
|
79
|
+
|
|
80
|
+
1. Open Claude Design → select the OTB project.
|
|
81
|
+
2. Describe the UI: "Build a task-card component matching the token palette."
|
|
82
|
+
3. Claude Design generates HTML/CSS/JS using `--dt-*` vars.
|
|
83
|
+
4. Iterate until the prototype is ready.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 4. Land the handoff as a GDS task
|
|
88
|
+
|
|
89
|
+
When Claude Design's output is ready:
|
|
90
|
+
|
|
91
|
+
**a. Claim a GDS task** (if not already done).
|
|
92
|
+
|
|
93
|
+
**b. Run the export step** — either via the skill or directly:
|
|
94
|
+
|
|
95
|
+
```js
|
|
96
|
+
const adapter = require('./src/ui/adapters/claude-design/index.js');
|
|
97
|
+
const result = await adapter.export({
|
|
98
|
+
repoRoot: process.cwd(),
|
|
99
|
+
surfaceId: 'hall-ui',
|
|
100
|
+
toolOutput: { files: [
|
|
101
|
+
{ path: 'components/TaskCard.js', content: '...' },
|
|
102
|
+
{ path: 'components/TaskCard.css', content: '...' },
|
|
103
|
+
]},
|
|
104
|
+
taskId: '1234',
|
|
105
|
+
});
|
|
106
|
+
// result: { filePaths, commitMessage, designSourcesUpdated, warnings }
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The adapter writes files to `src/ui/<surfaceId>/` and updates `config/design-sources.json` with the sync timestamp.
|
|
110
|
+
|
|
111
|
+
**c. Commit + ship.**
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
git add src/ui/hall-ui/ config/design-sources.json
|
|
115
|
+
git commit -m "ui(hall-ui): Claude Design export (task 1234)"
|
|
116
|
+
node scripts/gds/ship.js 1234 --notes "..." --summary "..."
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Iterating
|
|
122
|
+
|
|
123
|
+
- Re-run `node scripts/gds/design-sync.js` + re-push whenever tokens change.
|
|
124
|
+
- The `export()` call is **idempotent** — files with identical content are skipped.
|
|
125
|
+
- `config/design-sources.json` tracks which surface was last synced, by which tool, and when.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Coexisting with Figma
|
|
130
|
+
|
|
131
|
+
If a surface is Figma-canonical, its `config/design-sources.json` entry will have `"tool": "figma"`. The Claude Design adapter will still work on that surface, but treat the result as an experimental branch — the Figma-canonical surface won't round-trip cleanly. For code-canonical surfaces (the default), Claude Design is the right tool.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Troubleshooting
|
|
136
|
+
|
|
137
|
+
| Symptom | Fix |
|
|
138
|
+
|---|---|
|
|
139
|
+
| `design-sync: repoRoot is required` | Run from the repo root: `node scripts/gds/design-sync.js` |
|
|
140
|
+
| `design-tokens.neutral.json` missing | Run from a checkout that includes `config/`. |
|
|
141
|
+
| `path-escape` error from `export()` | Claude Design sent a path with `../` — reject that output and re-prompt. |
|
|
142
|
+
| Bundle is stale after token edit | Re-run `node scripts/gds/design-sync.js` and re-push. |
|
|
143
|
+
| DesignSync MCP not available | The MCP tool is session-specific — check your Claude Code session config. |
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Recipe — stand up claudebongos.com + geminibongos.com (vanity doors → cloudbongos.com)
|
|
2
|
+
|
|
3
|
+
> Brings **claudebongos.com** and **geminibongos.com** live as public "vanity
|
|
4
|
+
> doors": each shows the exact Cloud Bongos landing **gate** (`brand/cloud-bongos/gate`),
|
|
5
|
+
> rebranded to **"Claude Bongos" / `> claude`** (resp. **"Gemini Bongos" / `> gemini`**)
|
|
6
|
+
> at runtime — the visitor still types `bongos`, and on enter the gate redirects
|
|
7
|
+
> to **cloudbongos.com**, landing straight on the orbs. Same task also **promotes
|
|
8
|
+
> the gate onto the cloudbongos.com apex** (it replaces the buddha placeholder,
|
|
9
|
+
> which is what makes the redirect land "on the orbs"). Task
|
|
10
|
+
> [#1746](https://example.com/builders#/task/1746).
|
|
11
|
+
|
|
12
|
+
## Architecture (what we're building)
|
|
13
|
+
|
|
14
|
+
One gate bundle, three domains, a runtime switch — **no forked copies**. `space.js`
|
|
15
|
+
reads `location.hostname`; a door rebrands the entry + redirects on enter, and the
|
|
16
|
+
default (cloudbongos.com) reveals the orbs in place. Any future change to the gate
|
|
17
|
+
shows up on all three automatically.
|
|
18
|
+
|
|
19
|
+
| Domain | Serves | On typing `bongos` + enter |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| **claudebongos.com** | the gate, rebranded "Claude Bongos" / `> claude` | `→ https://cloudbongos.com/?entered=1` (orbs) |
|
|
22
|
+
| **geminibongos.com** | the gate, rebranded "Gemini Bongos" / `> gemini` | `→ https://cloudbongos.com/?entered=1` (orbs) |
|
|
23
|
+
| **cloudbongos.com** | the gate, "Cloud Bongos" (**was** the buddha page) | reveals the orbs in place |
|
|
24
|
+
|
|
25
|
+
Hosting is the **cheapest possible**, same as the staging gate:
|
|
26
|
+
|
|
27
|
+
| Thing | Value |
|
|
28
|
+
|---|---|
|
|
29
|
+
| Served by | Caddy `file_server`, web root `/home/lars/example/brand/cloud-bongos` |
|
|
30
|
+
| The two doors | **pure static** — no app process, no port, no password |
|
|
31
|
+
| cloudbongos.com apex | static gate for `/` + gate assets; **still proxies** `/api`, `/healthz`, etc. to the platform app (`:3002`) so sign-in keeps working |
|
|
32
|
+
| TLS | **one new Cloudflare Origin Cert per new domain** — the cloudbongos cert's SANs do NOT cover claudebongos.com / geminibongos.com |
|
|
33
|
+
| Cost | **$0/mo** — same droplet, no new process/port |
|
|
34
|
+
|
|
35
|
+
Why static (not a reverse-proxy block): the gate is plain HTML/CSS/JS + PNGs.
|
|
36
|
+
There is nothing to run. The `?entered=1` query flag is how a door hands off — the
|
|
37
|
+
gate honors it (only on non-door hosts) to skip its own entry and open the orbs.
|
|
38
|
+
|
|
39
|
+
Everything in the repo (`space.js`, the `infra/Caddyfile` blocks, the gate art)
|
|
40
|
+
auto-deploys to the droplet checkout on merge. What is **NOT** automatic — and is
|
|
41
|
+
this recipe — is the per-domain **DNS + Origin Cert** and the **live Caddyfile
|
|
42
|
+
merge + reload**. Until those are done, the two domains show a TLS error (expected).
|
|
43
|
+
|
|
44
|
+
## Phase ① — DNS (Cloudflare, ~1 min per domain)
|
|
45
|
+
|
|
46
|
+
Both domains are already on Cloudflare. For **each** zone (claudebongos.com,
|
|
47
|
+
geminibongos.com):
|
|
48
|
+
|
|
49
|
+
1. Cloudflare → pick the zone → **DNS** → **Add record**.
|
|
50
|
+
2. Type **A**, Name **`@`**, IPv4 **`REDACTED_IP`**, Proxy status **Proxied**
|
|
51
|
+
(orange cloud ON), TTL Auto. Save.
|
|
52
|
+
3. Cloudflare → **SSL/TLS** → **Overview** → set encryption mode to **Full (strict)**.
|
|
53
|
+
|
|
54
|
+
(Optional: add a **`www`** A record → same IP, proxied, if you want `www.` to work.
|
|
55
|
+
The Caddyfile blocks are apex-only today; add `www.claudebongos.com` to the site
|
|
56
|
+
line if you add the record.)
|
|
57
|
+
|
|
58
|
+
## Phase ② — Origin Certificate (own domain → own cert)
|
|
59
|
+
|
|
60
|
+
Each new domain needs its **own** Origin Cert. For **each** zone:
|
|
61
|
+
|
|
62
|
+
Cloudflare → **SSL/TLS → Origin Server → Create Certificate**:
|
|
63
|
+
- Hostnames: `claudebongos.com` **and** `*.claudebongos.com` (resp. the gemini pair)
|
|
64
|
+
- Let Cloudflare generate the key; **copy both** the certificate and the private key.
|
|
65
|
+
|
|
66
|
+
Install on the droplet (operator). Caddy runs as user `caddy` and **must be able to
|
|
67
|
+
READ the key** — match the existing `origin.key` ownership (`640 root:caddy`). A
|
|
68
|
+
root-only `600` key makes Caddy's reload fail (learned during the cloudbongos
|
|
69
|
+
bring-up). The `.crt` can be world-readable.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# claudebongos
|
|
73
|
+
sudo install -m 644 -g caddy /dev/stdin /etc/caddy/claudebongos-origin.crt # paste cert, Ctrl-D
|
|
74
|
+
sudo install -m 640 -g caddy /dev/stdin /etc/caddy/claudebongos-origin.key # paste key, Ctrl-D
|
|
75
|
+
# geminibongos
|
|
76
|
+
sudo install -m 644 -g caddy /dev/stdin /etc/caddy/geminibongos-origin.crt # paste cert, Ctrl-D
|
|
77
|
+
sudo install -m 640 -g caddy /dev/stdin /etc/caddy/geminibongos-origin.key # paste key, Ctrl-D
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Phase ③ — apply the Caddy blocks + reload
|
|
81
|
+
|
|
82
|
+
Three blocks ship in `infra/Caddyfile`: the two new **door** blocks
|
|
83
|
+
(`claudebongos.com`, `geminibongos.com`) and the **modified `cloudbongos.com`
|
|
84
|
+
apex** block (now serves the gate + proxies functional paths). The live
|
|
85
|
+
`/etc/caddy/Caddyfile` has drifted slightly from the repo copy, so **do not blindly
|
|
86
|
+
`cp` the whole file** — apply the two pieces by hand:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
cd /home/lars/example
|
|
90
|
+
git pull # or wait for the auto-deploy; the brand/ bundle + infra/Caddyfile land here
|
|
91
|
+
|
|
92
|
+
# 1. Append the two door blocks (idempotent: skip if already present).
|
|
93
|
+
grep -q '^claudebongos.com {' /etc/caddy/Caddyfile || \
|
|
94
|
+
awk '/^# ── Claude Bongos \+ Gemini Bongos — vanity DOORS/{p=1} p' infra/Caddyfile \
|
|
95
|
+
| sed '/^# ── Cloud Bongos — STAGING/,$d' >> /etc/caddy/Caddyfile
|
|
96
|
+
# (or just open the file and paste the two blocks from infra/Caddyfile — the
|
|
97
|
+
# awk above copies from the DOORS comment to end-of-file.)
|
|
98
|
+
|
|
99
|
+
# 2. Modify the LIVE cloudbongos.com apex block. Open the file, find the
|
|
100
|
+
# `cloudbongos.com {` block, and replace its body — the single
|
|
101
|
+
# `reverse_proxy 127.0.0.1:3002 { … }` — with the gate-serving body from
|
|
102
|
+
# infra/Caddyfile (root + @hidden + @gate handle + the catch-all reverse_proxy).
|
|
103
|
+
# Leave builders.cloudbongos.com and status.cloudbongos.com UNTOUCHED.
|
|
104
|
+
sudo nano /etc/caddy/Caddyfile
|
|
105
|
+
|
|
106
|
+
# 3. Validate (as root — it must read the 640 origin keys), then reload.
|
|
107
|
+
sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
|
|
108
|
+
sudo systemctl reload caddy # fails closed on a bad config
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
> A bad config makes `reload` error out and **keep serving the old config** — the
|
|
112
|
+
> live sites never go down. If a cert path is wrong, that one site fails to come
|
|
113
|
+
> up while the others keep serving.
|
|
114
|
+
|
|
115
|
+
## Phase ④ — verify
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# from anywhere — the two doors:
|
|
119
|
+
curl -sSL https://claudebongos.com/ | grep -o 'space.css\|gate' # gate HTML served ✓
|
|
120
|
+
curl -sSL https://geminibongos.com/ | grep -o 'space.css\|gate' # gate HTML served ✓
|
|
121
|
+
curl -sS -o /dev/null -w '%{http_code}\n' https://claudebongos.com/ # 200 (via the /gate/ redirect) ✓
|
|
122
|
+
|
|
123
|
+
# cloudbongos.com apex now serves the gate, and the app still answers:
|
|
124
|
+
curl -sSL https://cloudbongos.com/ | grep -o 'space.css\|gate' # gate served at apex ✓
|
|
125
|
+
curl -sS https://cloudbongos.com/healthz # "ok" — app still reachable ✓
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Then open each in **Chrome or Edge** (the live-glass refraction needs Chromium
|
|
129
|
+
`backdrop-filter` + SVG displacement; Safari falls back to a plain frost, still
|
|
130
|
+
fine):
|
|
131
|
+
|
|
132
|
+
- `https://claudebongos.com` → gate reads **"Claude Bongos" / `> claude`**. Type
|
|
133
|
+
`bongos`, press enter → you land on **cloudbongos.com showing the orbs**.
|
|
134
|
+
- `https://geminibongos.com` → same, **"Gemini Bongos" / `> gemini`**.
|
|
135
|
+
- `https://cloudbongos.com` → gate reads "Cloud Bongos"; type `bongos` → orbs in place.
|
|
136
|
+
- **Sign-in still works:** `https://builders.cloudbongos.com` → sign in with GitHub
|
|
137
|
+
(the OAuth callback is on the apex, `/api/gds/auth/web/callback`, which the
|
|
138
|
+
catch-all still proxies to `:3002`). If sign-in breaks, the apex `@gate`/`handle`
|
|
139
|
+
split is wrong — recheck step ③.2.
|
|
140
|
+
|
|
141
|
+
## Rollback
|
|
142
|
+
|
|
143
|
+
- **Take a door down:** delete its block from `/etc/caddy/Caddyfile`,
|
|
144
|
+
`sudo systemctl reload caddy`, remove the Cloudflare `@` A record.
|
|
145
|
+
- **Revert cloudbongos.com to the buddha page:** restore the apex block to the
|
|
146
|
+
single `reverse_proxy 127.0.0.1:3002 { … }` body, reload. The buddha landing
|
|
147
|
+
(`public-landing/index.html`) is untouched in the repo and served again
|
|
148
|
+
immediately.
|
|
149
|
+
|
|
150
|
+
## Files this recipe uses
|
|
151
|
+
|
|
152
|
+
- `infra/Caddyfile` — the two door blocks + the modified `cloudbongos.com` apex block.
|
|
153
|
+
- `brand/cloud-bongos/gate/space.js` — the runtime hostname switch (branding +
|
|
154
|
+
redirect + `?entered` auto-open).
|
|
155
|
+
- `brand/cloud-bongos/` — the gate bundle + the world art it refracts (shared by all three).
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Recipe — stand up staging.cloudbongos.com (password-locked landing-page preview)
|
|
2
|
+
|
|
3
|
+
> Brings up **staging.cloudbongos.com** — a password-locked preview of the Cloud Bongos
|
|
4
|
+
> landing **gate** (`brand/cloud-bongos/gate`, the cel-glass + `> cloud bongos` terminal
|
|
5
|
+
> prototype from tasks [#1532](https://example.com/builders#/task/1532) +
|
|
6
|
+
> [#1534](https://example.com/builders#/task/1534)). This is the future
|
|
7
|
+
> cloudbongos.com landing page, parked behind a shared password so it can be shared for
|
|
8
|
+
> review before it goes public. Task [#1540](https://example.com/builders#/task/1540).
|
|
9
|
+
|
|
10
|
+
## Architecture (what we're building)
|
|
11
|
+
|
|
12
|
+
The **cheapest possible** host: no app process, no new port, no new certificate. Caddy
|
|
13
|
+
**static-serves** the brand-art folder that already ships in the checkout, behind HTTP
|
|
14
|
+
basic auth (the password lock).
|
|
15
|
+
|
|
16
|
+
| Thing | Value |
|
|
17
|
+
|---|---|
|
|
18
|
+
| URL | `https://staging.cloudbongos.com` (redirects to `/gate/`, where the gate is served) |
|
|
19
|
+
| Served by | Caddy `file_server`, web root `/home/lars/example/brand/cloud-bongos` |
|
|
20
|
+
| Lock | HTTP basic auth — username `bongos` + a shared password |
|
|
21
|
+
| TLS | the existing `*.cloudbongos.com` origin + Cloudflare edge certs (already cover it) |
|
|
22
|
+
| Cost | **$0/mo** — same droplet, no process, no port |
|
|
23
|
+
|
|
24
|
+
Why static (not a reverse-proxy block like the others): the gate is plain HTML/CSS/JS +
|
|
25
|
+
PNGs. There is nothing to run. Caddy serves the files directly.
|
|
26
|
+
|
|
27
|
+
## Why the web root is the brand folder, not `gate/`
|
|
28
|
+
|
|
29
|
+
The gate page lives at `gate/index.html` but references its art **relative to `/gate/`** —
|
|
30
|
+
sprites **beside it** (`sprites/…`, `dispmaps/…`) and the world **one level up**
|
|
31
|
+
(`../world/…`). So the folder that must be the web root is `brand/cloud-bongos/` (the
|
|
32
|
+
parent), and the page must actually be served **at `/gate/`** for those relative paths to
|
|
33
|
+
resolve. The Caddy block therefore **redirects the apex `/` → `/gate/`** (`redir / /gate/`)
|
|
34
|
+
rather than serving the gate's HTML at the apex.
|
|
35
|
+
|
|
36
|
+
> History (task 1545): the block first tried to serve the gate AT the apex via
|
|
37
|
+
> `rewrite / /gate/index.html` plus per-folder rewrites (`/dispmaps/*` → `/gate/dispmaps/*`).
|
|
38
|
+
> That was fragile — when the gate gained `sprites/` (task 1541) those 404'd at the apex
|
|
39
|
+
> (the browser asked `/sprites/*`, not `/gate/sprites/*`). The redirect serves the gate at
|
|
40
|
+
> its native path so **all** relative folders resolve, with nothing to keep in sync.
|
|
41
|
+
|
|
42
|
+
## Phase ① — DNS (Cloudflare dashboard, ~30 s)
|
|
43
|
+
|
|
44
|
+
cloudbongos.com is on Cloudflare. Add **one** record:
|
|
45
|
+
|
|
46
|
+
1. Cloudflare → pick the **cloudbongos.com** zone → **DNS** → **Add record**.
|
|
47
|
+
2. Type **A**, Name **`staging`**, IPv4 **`REDACTED_IP`**, Proxy status **Proxied** (orange cloud ON), TTL Auto.
|
|
48
|
+
3. Save.
|
|
49
|
+
|
|
50
|
+
No new certificate is needed — the cloudbongos origin cert is already
|
|
51
|
+
`cloudbongos.com, *.cloudbongos.com`, and Cloudflare's edge cert covers
|
|
52
|
+
`staging.cloudbongos.com` too.
|
|
53
|
+
|
|
54
|
+
## Phase ② — the password (droplet, one-time)
|
|
55
|
+
|
|
56
|
+
The `staging.cloudbongos.com` block ships in `infra/Caddyfile` with a **dummy** bcrypt hash,
|
|
57
|
+
so no real secret is in git. Generate the real hash and keep it handy for Phase ③:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
caddy hash-password --plaintext 'YOUR_PASSWORD'
|
|
61
|
+
# → prints $2a$14$……… (copy the whole thing)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Username is `bongos`; the password is whatever you hashed. The real hash lives **only** in
|
|
65
|
+
the live `/etc/caddy/Caddyfile` — never committed.
|
|
66
|
+
|
|
67
|
+
## Phase ③ — apply the Caddy block + reload
|
|
68
|
+
|
|
69
|
+
The `staging.cloudbongos.com` block is already in `infra/Caddyfile`. The live
|
|
70
|
+
`/etc/caddy/Caddyfile` has drifted slightly from the repo copy (comment wording + block
|
|
71
|
+
order), so **do not blindly `cp` the whole file** — append just the new block, swap the
|
|
72
|
+
dummy hash for the real one, then reload:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
cd /home/lars/example
|
|
76
|
+
# 1. append only the staging.cloudbongos.com block (idempotent: skip if present)
|
|
77
|
+
grep -q 'staging.cloudbongos.com {' /etc/caddy/Caddyfile || \
|
|
78
|
+
awk '/^# ── Cloud Bongos — STAGING/{p=1} p' infra/Caddyfile >> /etc/caddy/Caddyfile
|
|
79
|
+
|
|
80
|
+
# 2. replace the dummy hash: open the file, find the staging.cloudbongos.com
|
|
81
|
+
# block's `basic_auth { bongos … }` line, and paste the real $2a$… hash from
|
|
82
|
+
# Phase ② in place of the dummy one.
|
|
83
|
+
sudo nano /etc/caddy/Caddyfile # or any editor
|
|
84
|
+
|
|
85
|
+
# 3. let the caddy user READ the static files. Caddy runs as user `caddy`, which
|
|
86
|
+
# cannot traverse the 750 home dir — without this, authenticated requests get
|
|
87
|
+
# 403. Everything under /home/lars/example is already world-readable, so
|
|
88
|
+
# ONLY the home dir itself needs to be traversable (one-time, persists):
|
|
89
|
+
sudo setfacl -m u:caddy:x /home/lars 2>/dev/null \
|
|
90
|
+
|| sudo chmod o+x /home/lars # fallback if the `acl` package is absent
|
|
91
|
+
# o+x allows traverse, not listing. For strict least-privilege instead of the
|
|
92
|
+
# broad o+x, `sudo apt-get install -y acl` first so the setfacl path is taken.
|
|
93
|
+
|
|
94
|
+
# 4. validate (as root — it must read the 640 root:caddy origin key), then reload
|
|
95
|
+
sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
|
|
96
|
+
sudo systemctl reload caddy # fails closed on a bad config
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
> A bad config makes `reload` error out and **keep serving the old config** — the live
|
|
100
|
+
> sites never go down. Leaving the dummy hash in place is also safe: it just means no one
|
|
101
|
+
> can log in (fail-closed) until you paste the real one.
|
|
102
|
+
|
|
103
|
+
## Phase ④ — verify
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# from anywhere:
|
|
107
|
+
curl -sS -o /dev/null -w '%{http_code}\n' https://staging.cloudbongos.com/ # 401 (locked) ✓
|
|
108
|
+
curl -sS -u bongos:YOUR_PASSWORD https://staging.cloudbongos.com/ | grep -o 'cloud bongos' # matches ✓
|
|
109
|
+
curl -sS -o /dev/null -w '%{http_code}\n' -u bongos:YOUR_PASSWORD \
|
|
110
|
+
https://staging.cloudbongos.com/world/assets/plates/scene-establishing.png # 200 (art loads) ✓
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Then open `https://staging.cloudbongos.com` in **Chrome or Edge** (the live-glass
|
|
114
|
+
refraction needs Chromium `backdrop-filter` + SVG displacement; Safari falls back to a
|
|
115
|
+
plain frost, which still looks fine). The browser shows a username/password box — enter
|
|
116
|
+
`bongos` + the password — and the gate appears.
|
|
117
|
+
|
|
118
|
+
## Rotating / removing the password
|
|
119
|
+
|
|
120
|
+
- **Change the password:** regenerate the hash (Phase ②), edit the `bongos …` line in the
|
|
121
|
+
`staging.cloudbongos.com` block of `/etc/caddy/Caddyfile`, `sudo systemctl reload caddy`.
|
|
122
|
+
- **Take the site down:** delete the `staging.cloudbongos.com` block from
|
|
123
|
+
`/etc/caddy/Caddyfile`, `sudo systemctl reload caddy`, and remove the Cloudflare
|
|
124
|
+
`staging` A record.
|
|
125
|
+
|
|
126
|
+
## Later — promote to the real public landing page
|
|
127
|
+
|
|
128
|
+
When the gate is approved as the public landing page, that is a **separate task**: fold the
|
|
129
|
+
gate into `public-landing/index.html` (served at the cloudbongos.com apex by
|
|
130
|
+
`platform-server.js`), bring the world art it needs under a served path, and drop the basic
|
|
131
|
+
auth. Until then, this staging block is the review surface and `public-landing/index.html`
|
|
132
|
+
stays the minimal buddha placeholder.
|
|
133
|
+
|
|
134
|
+
## Files this recipe uses
|
|
135
|
+
|
|
136
|
+
- `infra/Caddyfile` — the `staging.cloudbongos.com` block (ships with a dummy hash; the
|
|
137
|
+
live file carries the real one).
|
|
138
|
+
- `brand/cloud-bongos/gate/` — the gate prototype (`index.html` + `dispmaps/`).
|
|
139
|
+
- `brand/cloud-bongos/world/assets/` — the art the gate refracts.
|