@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,183 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Apply any unapplied SQL files to the local Postgres, from THREE roots (ADR 0108 §5,
|
|
3
|
+
# configurable-root W5): the CORE package's migrations/, the INSTANCE's migrations/instance/,
|
|
4
|
+
# and each enabled MODULE's migrations/. Each migration is named NNN_name.sql — or a namespaced
|
|
5
|
+
# core_NNN_/<key>_NNN_ (ADR 0108 §5) — and tracked in schema_migrations by its filename STEM.
|
|
6
|
+
# Idempotent.
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# --- Resolve the core + instance roots (ADR 0108 configurable-root) -------
|
|
11
|
+
# TWO roots, resolved via src/instance-config.js. Today the core lives at the repo root
|
|
12
|
+
# alongside the instance, so both resolve to the SAME dir and this is byte-identical to the
|
|
13
|
+
# old `cd "$(dirname "$0")/.."`. Once the core installs from node_modules, resolveCoreRoot()
|
|
14
|
+
# points into the package (core migrations + src/) while resolveInstanceRoot() stays the host
|
|
15
|
+
# repo (env → bongos.config → cwd). We resolve from the SCRIPT-relative dir so the result does
|
|
16
|
+
# not depend on the caller's cwd (preserving the old script-relative behavior), and fail open to
|
|
17
|
+
# that dir if node is unavailable so a deploy never breaks.
|
|
18
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
19
|
+
DEFAULT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
20
|
+
CORE_ROOT="$(cd "$DEFAULT_ROOT" && node -e "process.stdout.write(require('./src/instance-config').resolveCoreRoot())" 2>/dev/null || echo "$DEFAULT_ROOT")"
|
|
21
|
+
INSTANCE_ROOT="$(cd "$DEFAULT_ROOT" && node -e "process.stdout.write(require('./src/instance-config').resolveInstanceRoot())" 2>/dev/null || echo "$DEFAULT_ROOT")"
|
|
22
|
+
# Run from the instance root so instance-relative paths resolve (the post-deploy art check below)
|
|
23
|
+
# AND so the enabledModules() read finds the instance's config/modules.json (resolveInstanceRoot
|
|
24
|
+
# falls back to cwd).
|
|
25
|
+
cd "$INSTANCE_ROOT"
|
|
26
|
+
|
|
27
|
+
DB="${PGDATABASE:-amazonprimea}"
|
|
28
|
+
|
|
29
|
+
# --- Instance-seed policy (task 1704 / ADR 0105) --------------------------
|
|
30
|
+
# OTB/product scope-truth (versions, goals, done_when_criteria) lives in seed
|
|
31
|
+
# migrations under migrations/instance/ (plus a few guarded blocks embedded in the
|
|
32
|
+
# mixed schema+seed files 003/006). These must NOT run on a fresh non-owning DB:
|
|
33
|
+
# on a vanilla self-host they FK-crash the boot (the 2026-07-02 regression,
|
|
34
|
+
# tactically patched in 172/173); on a branded third-party instance they'd pollute
|
|
35
|
+
# it with OTB's versions/goals. So instance seeds are OPT-IN and DEFAULT OFF.
|
|
36
|
+
#
|
|
37
|
+
# The owning instance turns them on explicitly (GDS_APPLY_INSTANCE_SEEDS=1) only
|
|
38
|
+
# when rebuilding its DB from scratch (the DR runbook). A normal OTB deploy never
|
|
39
|
+
# needs it — those rows are already recorded in schema_migrations, so they're
|
|
40
|
+
# skipped as-applied regardless. MEDUSA_GDS_ONLY=1 (the self-host marker set in
|
|
41
|
+
# docker-compose.yml) HARD force-skips even if the opt-in is present.
|
|
42
|
+
#
|
|
43
|
+
# SEED_INSTANCE does two things below: (1) gates whether migrations/instance/*.sql
|
|
44
|
+
# are applied at all, and (2) is exposed to SQL as the app.seed_instance_data GUC
|
|
45
|
+
# (via PGOPTIONS, inherited by every psql), so the unavoidable instance-seed blocks
|
|
46
|
+
# embedded in the mixed migrations 003/006 guard on it.
|
|
47
|
+
if [ -n "${MEDUSA_GDS_ONLY:-}" ]; then
|
|
48
|
+
SEED_INSTANCE=off
|
|
49
|
+
elif [ "${GDS_APPLY_INSTANCE_SEEDS:-0}" = "1" ]; then
|
|
50
|
+
SEED_INSTANCE=on
|
|
51
|
+
else
|
|
52
|
+
SEED_INSTANCE=off
|
|
53
|
+
fi
|
|
54
|
+
export PGOPTIONS="${PGOPTIONS:+$PGOPTIONS }-c app.seed_instance_data=$SEED_INSTANCE"
|
|
55
|
+
echo "instance-seed policy: app.seed_instance_data=$SEED_INSTANCE (migrations/instance/ $([ "$SEED_INSTANCE" = "on" ] && echo applied || echo skipped))"
|
|
56
|
+
|
|
57
|
+
# Make sure schema_migrations exists before we query it. (001 creates
|
|
58
|
+
# it; other migrations rely on it.)
|
|
59
|
+
psql -d "$DB" -v ON_ERROR_STOP=1 -tAc "
|
|
60
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
61
|
+
version text PRIMARY KEY,
|
|
62
|
+
applied_at timestamptz NOT NULL DEFAULT now()
|
|
63
|
+
);
|
|
64
|
+
" >/dev/null
|
|
65
|
+
|
|
66
|
+
APPLIED=$(psql -d "$DB" -tA -c "SELECT version FROM schema_migrations ORDER BY version")
|
|
67
|
+
|
|
68
|
+
# Apply one migration file unless its filename stem is already recorded. Stem (not path) is the
|
|
69
|
+
# key, so moving a file between migrations/ and migrations/game/ does NOT re-run it on prod.
|
|
70
|
+
apply_migration() {
|
|
71
|
+
local f="$1" version
|
|
72
|
+
version="$(basename "$f" .sql)"
|
|
73
|
+
if echo "$APPLIED" | grep -q "^${version}$"; then
|
|
74
|
+
echo "skip $version (already applied)"
|
|
75
|
+
return
|
|
76
|
+
fi
|
|
77
|
+
echo "apply $version"
|
|
78
|
+
psql -d "$DB" -v ON_ERROR_STOP=1 -f "$f"
|
|
79
|
+
# Self-register the apply. Most migrations contain their own INSERT INTO
|
|
80
|
+
# schema_migrations, but ~14 of the historical files do not — for those,
|
|
81
|
+
# this is what keeps them from re-running on the next deploy. ON CONFLICT
|
|
82
|
+
# DO NOTHING means it's safe for files that DO self-register too.
|
|
83
|
+
psql -d "$DB" -v ON_ERROR_STOP=1 -tAc \
|
|
84
|
+
"INSERT INTO schema_migrations (version) VALUES ('${version}') ON CONFLICT DO NOTHING" \
|
|
85
|
+
>/dev/null
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# Build the ordered migration list and apply it as ONE numeric sequence by
|
|
89
|
+
# filename stem, regardless of directory:
|
|
90
|
+
# $CORE_ROOT/migrations/*.sql — core: schema + platform-universal seeds (EVERY instance).
|
|
91
|
+
# $INSTANCE_ROOT/migrations/instance/*.sql — OTB/product scope-truth (owning instance only; policy above).
|
|
92
|
+
# MERGING both dirs and sorting by BASENAME preserves the original global order — e.g.
|
|
93
|
+
# instance seed 018 still applies before core rename 019 — so a from-scratch replay
|
|
94
|
+
# matches history. New namespaced files (core_NNN_, ADR 0108 §5) sort AFTER the legacy bare
|
|
95
|
+
# block (a letter sorts after a digit), the correct "newer applies later" order. Instance files
|
|
96
|
+
# are included only when SEED_INSTANCE=on; stem-keyed tracking means a file's directory never
|
|
97
|
+
# affects whether it re-runs on OTB prod. Today CORE_ROOT == INSTANCE_ROOT (single checkout);
|
|
98
|
+
# once the core installs from node_modules the two roots diverge and this still merges correctly.
|
|
99
|
+
MIGRATIONS=$( {
|
|
100
|
+
ls "$CORE_ROOT"/migrations/*.sql 2>/dev/null
|
|
101
|
+
if [ "$SEED_INSTANCE" = "on" ]; then ls "$INSTANCE_ROOT"/migrations/instance/*.sql 2>/dev/null; fi
|
|
102
|
+
} | awk -F/ '{ print $NF "\t" $0 }' | sort | cut -f2- )
|
|
103
|
+
for f in $MIGRATIONS; do
|
|
104
|
+
[ -e "$f" ] || continue
|
|
105
|
+
apply_migration "$f"
|
|
106
|
+
done
|
|
107
|
+
[ "$SEED_INSTANCE" = "on" ] || echo "instance seeds skipped (migrations/instance/) — non-owning / vanilla instance"
|
|
108
|
+
|
|
109
|
+
# Module-owned migrations (modules/<key>/migrations/*.sql) — applied only when the module is
|
|
110
|
+
# enabled. The enablement is read from the instance's config/modules.json (or the neutral
|
|
111
|
+
# starter). The module CODE lives in the core package (require $CORE_ROOT/src/modules), but the
|
|
112
|
+
# config is instance content (resolveInstanceRoot() falls back to cwd == INSTANCE_ROOT, set
|
|
113
|
+
# above). The stem-key guarantee means moving a migration from migrations/game/ to
|
|
114
|
+
# modules/game/migrations/ does NOT re-run it on prod — schema_migrations is keyed by filename
|
|
115
|
+
# stem alone (ADR 0083 / BV1.R49, task 1418). A vanilla instance leaves game disabled via
|
|
116
|
+
# config/modules.neutral.json.
|
|
117
|
+
NODE_ENABLED_MODULES=$(node -e "
|
|
118
|
+
try {
|
|
119
|
+
const { enabledModules } = require('$CORE_ROOT/src/modules');
|
|
120
|
+
process.stdout.write(enabledModules().join(' '));
|
|
121
|
+
} catch(e) {
|
|
122
|
+
process.stderr.write('migrate.sh: could not read module config: ' + e.message + '\n');
|
|
123
|
+
process.stdout.write('');
|
|
124
|
+
}
|
|
125
|
+
" 2>/dev/null || true)
|
|
126
|
+
|
|
127
|
+
# Modules can be shipped by the CORE package or by the INSTANCE repo, so scan modules/ under
|
|
128
|
+
# BOTH roots. Apply each module key ONCE — today the two roots coincide (so instance-root modules
|
|
129
|
+
# are all already seen), and after the split a core module and an instance module never share a
|
|
130
|
+
# key (the loader errors on a cross-root key collision — ADR 0108).
|
|
131
|
+
SEEN_MODULE_KEYS=" "
|
|
132
|
+
for root in "$CORE_ROOT" "$INSTANCE_ROOT"; do
|
|
133
|
+
for mod_dir in "$root"/modules/*/; do
|
|
134
|
+
[ -d "$mod_dir" ] || continue
|
|
135
|
+
mod_key=$(basename "$mod_dir")
|
|
136
|
+
case "$SEEN_MODULE_KEYS" in *" $mod_key "*) continue ;; esac
|
|
137
|
+
SEEN_MODULE_KEYS="$SEEN_MODULE_KEYS$mod_key "
|
|
138
|
+
mig_dir="${mod_dir}migrations"
|
|
139
|
+
[ -d "$mig_dir" ] || continue
|
|
140
|
+
# Check if this module is enabled
|
|
141
|
+
if ! echo " $NODE_ENABLED_MODULES " | grep -q " $mod_key "; then
|
|
142
|
+
echo "module $mod_key disabled — skipping ${mig_dir}/*.sql"
|
|
143
|
+
continue
|
|
144
|
+
fi
|
|
145
|
+
for f in "$mig_dir"/*.sql; do
|
|
146
|
+
[ -e "$f" ] || continue
|
|
147
|
+
apply_migration "$f"
|
|
148
|
+
done
|
|
149
|
+
done
|
|
150
|
+
done
|
|
151
|
+
|
|
152
|
+
echo "done."
|
|
153
|
+
|
|
154
|
+
# ---------- post-deploy whole-world regression check (GDS #151 / E.1) ----------
|
|
155
|
+
#
|
|
156
|
+
# Renders the live world to a PNG, scores it via Gemini vision, and compares
|
|
157
|
+
# the score to the previous deploy. Fails the script (exit 1) if the score
|
|
158
|
+
# drops more than 1.0 point — catches asset-swap regressions that per-tile
|
|
159
|
+
# review misses (e.g. grass becomes tan, container becomes invisible).
|
|
160
|
+
#
|
|
161
|
+
# Gated on OTB_POST_DEPLOY_CHECK=1 so the droplet's ~/deploy.sh path (which
|
|
162
|
+
# calls this script) stays unaffected — the droplet has no Google API key
|
|
163
|
+
# and no Python pillow installed by default. The check runs from a deploy
|
|
164
|
+
# wrapper on the dev machine that sets the flag.
|
|
165
|
+
if [ "${OTB_POST_DEPLOY_CHECK:-0}" = "1" ]; then
|
|
166
|
+
echo
|
|
167
|
+
echo "post-deploy: running whole-world regression check"
|
|
168
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
169
|
+
# Baseline-only on first invocation: if the ledger doesn't yet exist,
|
|
170
|
+
# save the score without failing (we have no prior to compare against).
|
|
171
|
+
BASELINE_FLAG=""
|
|
172
|
+
if [ ! -s art/iterations/world_scores.jsonl ]; then
|
|
173
|
+
BASELINE_FLAG="--baseline-only"
|
|
174
|
+
echo "post-deploy: no prior score ledger — running in baseline-only mode"
|
|
175
|
+
fi
|
|
176
|
+
if ! python3 modules/art-pipeline/pipeline/post_deploy_check.py $BASELINE_FLAG; then
|
|
177
|
+
echo "post-deploy: whole-world check FAILED — see output above" >&2
|
|
178
|
+
exit 1
|
|
179
|
+
fi
|
|
180
|
+
else
|
|
181
|
+
echo "post-deploy: python3 not found — skipping whole-world check" >&2
|
|
182
|
+
fi
|
|
183
|
+
fi
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scripts/migrate_cost_ledger.sh
|
|
3
|
+
#
|
|
4
|
+
# One-shot (idempotent) migration: fold any per-worktree
|
|
5
|
+
# art/iterations/cost_ledger.jsonl files into the shared location at
|
|
6
|
+
# ~/.config/otb/iterations/cost_ledger.jsonl, then rebuild cost_summary.json
|
|
7
|
+
# from the merged ledger.
|
|
8
|
+
#
|
|
9
|
+
# Per GDS #140 (2026-05-10 Lars decision): the ledger lives next to
|
|
10
|
+
# pms-session.json + GOOGLE_AI_STUDIO_KEY in $HOME so it survives worktree churn
|
|
11
|
+
# the way the API key does.
|
|
12
|
+
#
|
|
13
|
+
# Safe to re-run: appends only ledger rows not already present in the shared
|
|
14
|
+
# file (matched by (ts, model, kind, tile, attempt, cost_usd, notes) tuple).
|
|
15
|
+
# Per-worktree files are renamed to *.migrated-<timestamp> instead of deleted,
|
|
16
|
+
# so nothing is destroyed.
|
|
17
|
+
#
|
|
18
|
+
# Usage:
|
|
19
|
+
# scripts/migrate_cost_ledger.sh # search standard locations
|
|
20
|
+
# scripts/migrate_cost_ledger.sh <ledger> [...] # explicit files to fold in
|
|
21
|
+
# OTB_LEDGER_DIR=/tmp/foo scripts/migrate_cost_ledger.sh # override target
|
|
22
|
+
|
|
23
|
+
set -euo pipefail
|
|
24
|
+
|
|
25
|
+
SHARED_DIR="${OTB_LEDGER_DIR:-$HOME/.config/otb/iterations}"
|
|
26
|
+
SHARED_LEDGER="$SHARED_DIR/cost_ledger.jsonl"
|
|
27
|
+
SHARED_SUMMARY="$SHARED_DIR/cost_summary.json"
|
|
28
|
+
|
|
29
|
+
mkdir -p "$SHARED_DIR"
|
|
30
|
+
touch "$SHARED_LEDGER"
|
|
31
|
+
|
|
32
|
+
# Build candidate list: explicit args win, otherwise sweep common locations.
|
|
33
|
+
declare -a CANDIDATES=()
|
|
34
|
+
if [ "$#" -gt 0 ]; then
|
|
35
|
+
CANDIDATES=("$@")
|
|
36
|
+
else
|
|
37
|
+
# Repo root (this script lives in <root>/scripts/).
|
|
38
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
39
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
40
|
+
|
|
41
|
+
# 1. The current repo's per-worktree ledger.
|
|
42
|
+
[ -f "$REPO_ROOT/art/iterations/cost_ledger.jsonl" ] && \
|
|
43
|
+
CANDIDATES+=("$REPO_ROOT/art/iterations/cost_ledger.jsonl")
|
|
44
|
+
|
|
45
|
+
# 2. Any sibling worktrees of this repo.
|
|
46
|
+
if [ -d "$REPO_ROOT/.claude/worktrees" ]; then
|
|
47
|
+
while IFS= read -r p; do
|
|
48
|
+
CANDIDATES+=("$p")
|
|
49
|
+
done < <(find "$REPO_ROOT/.claude/worktrees" -mindepth 2 -maxdepth 4 \
|
|
50
|
+
-type f -name cost_ledger.jsonl 2>/dev/null)
|
|
51
|
+
fi
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# De-dup the candidate list AND drop the shared-ledger path itself if it snuck in.
|
|
55
|
+
# (Stays portable to macOS default bash 3.2 — no associative arrays.)
|
|
56
|
+
SHARED_REAL="$(cd "$SHARED_DIR" && pwd)/cost_ledger.jsonl"
|
|
57
|
+
SEEN_LIST=""
|
|
58
|
+
FILTERED=()
|
|
59
|
+
for c in "${CANDIDATES[@]+"${CANDIDATES[@]}"}"; do
|
|
60
|
+
[ -f "$c" ] || continue
|
|
61
|
+
REAL="$(cd "$(dirname "$c")" && pwd)/$(basename "$c")"
|
|
62
|
+
[ "$REAL" = "$SHARED_REAL" ] && continue
|
|
63
|
+
case "$SEEN_LIST" in
|
|
64
|
+
*"|$REAL|"*) continue ;;
|
|
65
|
+
esac
|
|
66
|
+
SEEN_LIST="$SEEN_LIST|$REAL|"
|
|
67
|
+
FILTERED+=("$REAL")
|
|
68
|
+
done
|
|
69
|
+
|
|
70
|
+
if [ "${#FILTERED[@]}" -eq 0 ]; then
|
|
71
|
+
echo "No per-worktree cost_ledger.jsonl files to migrate."
|
|
72
|
+
echo "Shared ledger: $SHARED_LEDGER"
|
|
73
|
+
# Still rebuild the summary so a fresh shared dir gets a summary file.
|
|
74
|
+
python3 "$(dirname "$0")/../modules/art-pipeline/pipeline/cost_ledger.py" status >/dev/null || true
|
|
75
|
+
exit 0
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
echo "Migrating to: $SHARED_LEDGER"
|
|
79
|
+
for f in "${FILTERED[@]}"; do echo " source: $f"; done
|
|
80
|
+
|
|
81
|
+
# Python does the dedup + merge + summary rebuild. Keeps the bash side simple
|
|
82
|
+
# and gives us proper JSON-aware comparison.
|
|
83
|
+
python3 - "$SHARED_LEDGER" "$SHARED_SUMMARY" "${FILTERED[@]}" <<'PYEOF'
|
|
84
|
+
import json, os, sys, time
|
|
85
|
+
from pathlib import Path
|
|
86
|
+
|
|
87
|
+
shared_ledger = Path(sys.argv[1])
|
|
88
|
+
shared_summary = Path(sys.argv[2])
|
|
89
|
+
sources = [Path(p) for p in sys.argv[3:]]
|
|
90
|
+
|
|
91
|
+
def row_key(r: dict) -> tuple:
|
|
92
|
+
# Identity: (ts, model, kind, tile, attempt, cost_usd, notes).
|
|
93
|
+
# No `id` column exists today, so dedup by content tuple.
|
|
94
|
+
return (
|
|
95
|
+
r.get("ts", ""),
|
|
96
|
+
r.get("model", ""),
|
|
97
|
+
r.get("kind", ""),
|
|
98
|
+
r.get("tile", ""),
|
|
99
|
+
r.get("attempt", 0),
|
|
100
|
+
round(float(r.get("cost_usd", 0.0)), 6),
|
|
101
|
+
r.get("notes", ""),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
existing_keys: set = set()
|
|
105
|
+
if shared_ledger.exists():
|
|
106
|
+
with shared_ledger.open() as f:
|
|
107
|
+
for line in f:
|
|
108
|
+
line = line.strip()
|
|
109
|
+
if not line:
|
|
110
|
+
continue
|
|
111
|
+
try:
|
|
112
|
+
existing_keys.add(row_key(json.loads(line)))
|
|
113
|
+
except Exception:
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
added = 0
|
|
117
|
+
skipped_dup = 0
|
|
118
|
+
skipped_bad = 0
|
|
119
|
+
ts_suffix = time.strftime("%Y%m%dT%H%M%S")
|
|
120
|
+
|
|
121
|
+
with shared_ledger.open("a") as out:
|
|
122
|
+
for src in sources:
|
|
123
|
+
if not src.exists():
|
|
124
|
+
continue
|
|
125
|
+
with src.open() as f:
|
|
126
|
+
for line in f:
|
|
127
|
+
line_stripped = line.strip()
|
|
128
|
+
if not line_stripped:
|
|
129
|
+
continue
|
|
130
|
+
try:
|
|
131
|
+
row = json.loads(line_stripped)
|
|
132
|
+
except Exception:
|
|
133
|
+
skipped_bad += 1
|
|
134
|
+
continue
|
|
135
|
+
k = row_key(row)
|
|
136
|
+
if k in existing_keys:
|
|
137
|
+
skipped_dup += 1
|
|
138
|
+
continue
|
|
139
|
+
existing_keys.add(k)
|
|
140
|
+
out.write(line if line.endswith("\n") else line_stripped + "\n")
|
|
141
|
+
added += 1
|
|
142
|
+
# Rename source so a re-run doesn't re-process it AND nothing is destroyed.
|
|
143
|
+
try:
|
|
144
|
+
src.rename(src.with_suffix(src.suffix + f".migrated-{ts_suffix}"))
|
|
145
|
+
print(f" archived: {src} → {src.name}.migrated-{ts_suffix}")
|
|
146
|
+
except OSError as e:
|
|
147
|
+
print(f" warn: could not rename {src}: {e}", file=sys.stderr)
|
|
148
|
+
|
|
149
|
+
# Rebuild summary from the merged ledger.
|
|
150
|
+
total = 0.0
|
|
151
|
+
n = 0
|
|
152
|
+
with shared_ledger.open() as f:
|
|
153
|
+
for line in f:
|
|
154
|
+
line = line.strip()
|
|
155
|
+
if not line:
|
|
156
|
+
continue
|
|
157
|
+
try:
|
|
158
|
+
total += float(json.loads(line).get("cost_usd", 0.0))
|
|
159
|
+
n += 1
|
|
160
|
+
except Exception:
|
|
161
|
+
pass
|
|
162
|
+
|
|
163
|
+
HARD_STOP = 80.00
|
|
164
|
+
shared_summary.parent.mkdir(parents=True, exist_ok=True)
|
|
165
|
+
shared_summary.write_text(json.dumps({
|
|
166
|
+
"total_usd": round(total, 4),
|
|
167
|
+
"calls": n,
|
|
168
|
+
"hard_stop_usd": HARD_STOP,
|
|
169
|
+
"remaining_usd": round(HARD_STOP - total, 4),
|
|
170
|
+
"updated_at": time.strftime("%Y-%m-%dT%H:%M:%S"),
|
|
171
|
+
}, indent=2))
|
|
172
|
+
|
|
173
|
+
print(f"\nMerged: {added} new rows, {skipped_dup} duplicates skipped, {skipped_bad} malformed lines skipped.")
|
|
174
|
+
print(f"Shared ledger now: {n} rows, ${total:.4f} spent of ${HARD_STOP:.2f} cap.")
|
|
175
|
+
PYEOF
|
|
176
|
+
|
|
177
|
+
echo
|
|
178
|
+
echo "Done. Verify with: python3 modules/art-pipeline/pipeline/cost_ledger.py status"
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// scripts/public-mirror-export.js — the TIME-DELAYED, REDACTED export to the Cloud
|
|
5
|
+
// Bongos public mirror. GDS-V4 R72 (task 1211), implementing ADR 0098 + ADR 0065 §4.
|
|
6
|
+
//
|
|
7
|
+
// WHAT IT DOES, in one fail-closed pass:
|
|
8
|
+
// 1. Pick the SNAPSHOT commit: the newest commit on the source ref whose committer
|
|
9
|
+
// date is >= LAG_DAYS old (default 180 ≈ 6 months). The mirror is always ~6 months
|
|
10
|
+
// behind, by construction.
|
|
11
|
+
// 2. Enumerate that commit's tree and PARTITION it through publish-manifest.isPublishable
|
|
12
|
+
// — the SINGLE source of truth for what publishes (task 1210). No second allow-list.
|
|
13
|
+
// 3. REDACT every publishable file IN MEMORY: instance literals + public IPs
|
|
14
|
+
// (mirror-redact) then the secret backstop (secret-scrub). Binary files are kept
|
|
15
|
+
// verbatim but still leak-scanned.
|
|
16
|
+
// 4. NO-LEAK GATE (fail-closed): scan the redacted bytes of every file. If ANY instance
|
|
17
|
+
// literal, public IP, or secret survives, PUBLISH NOTHING — the mirror filesystem is
|
|
18
|
+
// never touched. This is why redaction happens in memory first: an abort is atomic.
|
|
19
|
+
// 5. Only when the whole set is clean: clear the mirror tree, write the redacted files
|
|
20
|
+
// (modes preserved), write .mirror-provenance.json (the lineage anchor R73 reads),
|
|
21
|
+
// commit, and (with --push) push.
|
|
22
|
+
//
|
|
23
|
+
// The 6-month delay alone does NOT scrub secrets/topology — redaction is mandatory and
|
|
24
|
+
// the gate is the backstop. Reuses the status-mirror-sync transport shape (--repo-dir /
|
|
25
|
+
// --push + a scoped deploy key, see .github/workflows/sync-public-mirror.yml).
|
|
26
|
+
//
|
|
27
|
+
// USAGE:
|
|
28
|
+
// node scripts/public-mirror-export.js --repo-dir <mirror-checkout> [--push]
|
|
29
|
+
// [--lag-days 180] [--source-ref origin/main] [--droplet-ip <ip>]
|
|
30
|
+
// Without --push: redacts + gates + writes the tree, prints `git status`, does NOT
|
|
31
|
+
// commit/push (a dry run you can inspect). With --push: commits + pushes HEAD:main.
|
|
32
|
+
// --droplet-ip (or env DROPLET_IP) adds the prod IP as an exact extra literal so the
|
|
33
|
+
// gate asserts that specific value is gone — belt-and-suspenders over the public-IP
|
|
34
|
+
// floor, and kept OUT of every committed file (sourced at publish time).
|
|
35
|
+
|
|
36
|
+
const fs = require('node:fs');
|
|
37
|
+
const path = require('node:path');
|
|
38
|
+
const { execFileSync } = require('node:child_process');
|
|
39
|
+
|
|
40
|
+
const REPO_ROOT = path.resolve(__dirname, '..');
|
|
41
|
+
const { isPublishable } = require(path.join(REPO_ROOT, 'scripts/gds/publish-manifest.js'));
|
|
42
|
+
const {
|
|
43
|
+
buildRedactionRules, collectSensitiveLiterals, redactText, findLeaks, findSecretLeak,
|
|
44
|
+
} = require(path.join(REPO_ROOT, 'scripts/gds/mirror-redact.js'));
|
|
45
|
+
const { collectEnvSecrets, scrubSecrets } = require(path.join(REPO_ROOT, 'modules/security/secret-scrub.js'));
|
|
46
|
+
|
|
47
|
+
const PROVENANCE_FILE = '.mirror-provenance.json';
|
|
48
|
+
const DEFAULT_LAG_DAYS = 180;
|
|
49
|
+
|
|
50
|
+
// ---- arg parsing ----------------------------------------------------------
|
|
51
|
+
function arg(name, fallback = null) {
|
|
52
|
+
const i = process.argv.indexOf(name);
|
|
53
|
+
return i >= 0 && i + 1 < process.argv.length ? process.argv[i + 1] : fallback;
|
|
54
|
+
}
|
|
55
|
+
function hasFlag(name) { return process.argv.includes(name); }
|
|
56
|
+
|
|
57
|
+
// ---- pure helpers (exported for tests) ------------------------------------
|
|
58
|
+
|
|
59
|
+
// Pick the newest commit at least LAG_DAYS old. `commits` is newest-first
|
|
60
|
+
// [{ sha, epoch }] (epoch = committer date, UNIX seconds). Returns the commit or null
|
|
61
|
+
// if the whole history is younger than the lag (a young repo: nothing to publish yet).
|
|
62
|
+
function pickSnapshotCommit(commits, nowMs, lagDays) {
|
|
63
|
+
const cutoffMs = nowMs - lagDays * 86400 * 1000;
|
|
64
|
+
for (const c of commits || []) {
|
|
65
|
+
if (typeof c.epoch === 'number' && c.epoch * 1000 <= cutoffMs) return c;
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Parse `git ls-tree -r <sha>` output → [{ mode, type, sha, path }] (blobs + the rest).
|
|
71
|
+
function parseLsTree(output) {
|
|
72
|
+
const out = [];
|
|
73
|
+
for (const line of String(output || '').split('\n')) {
|
|
74
|
+
if (!line.trim()) continue;
|
|
75
|
+
// "<mode> <type> <objsha>\t<path>"
|
|
76
|
+
const tab = line.indexOf('\t');
|
|
77
|
+
if (tab < 0) continue;
|
|
78
|
+
const meta = line.slice(0, tab).split(/\s+/);
|
|
79
|
+
if (meta.length < 3) continue;
|
|
80
|
+
out.push({ mode: meta[0], type: meta[1], sha: meta[2], path: line.slice(tab + 1) });
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Heuristic binary sniff: a NUL byte in the first 8 KiB. Mirrors how git decides.
|
|
86
|
+
function isBinary(buf) {
|
|
87
|
+
if (!Buffer.isBuffer(buf)) return false;
|
|
88
|
+
const n = Math.min(buf.length, 8192);
|
|
89
|
+
for (let i = 0; i < n; i++) if (buf[i] === 0) return true;
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Redact one blob and report any residual leak. Text files are redacted (instance
|
|
94
|
+
// literals + IP, then secret scrub); binary files are kept verbatim but leak-scanned
|
|
95
|
+
// over their latin1 view (so an embedded literal still trips the gate). The gate uses
|
|
96
|
+
// `sensitiveLiterals` (raw substrings), NOT `rules` — stricter than redaction on
|
|
97
|
+
// purpose (see mirror-redact.js). Returns { buf:Buffer, leaks:[{label,sample}], secret:boolean }.
|
|
98
|
+
function redactBlob({ buf, rules, sensitiveLiterals, envSecrets }) {
|
|
99
|
+
if (isBinary(buf)) {
|
|
100
|
+
const view = buf.toString('latin1');
|
|
101
|
+
return { buf, leaks: findLeaks(view, sensitiveLiterals), secret: findSecretLeak(view, envSecrets) };
|
|
102
|
+
}
|
|
103
|
+
const redacted = redactText(buf.toString('utf8'), rules);
|
|
104
|
+
const scrubbed = scrubSecrets(redacted, envSecrets);
|
|
105
|
+
return {
|
|
106
|
+
buf: Buffer.from(scrubbed, 'utf8'),
|
|
107
|
+
leaks: findLeaks(scrubbed, sensitiveLiterals),
|
|
108
|
+
secret: findSecretLeak(scrubbed, envSecrets),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function buildProvenance({ sourceCommit, committedAtIso, lagDays, fileCount, nowIso }) {
|
|
113
|
+
return {
|
|
114
|
+
_note: 'Lineage anchor for the Cloud Bongos public mirror (ADR 0098 / GDS-V4 R72). '
|
|
115
|
+
+ 'This mirror is a redacted, time-delayed snapshot of the private build repo. The '
|
|
116
|
+
+ 'R73 proof (#1212) asserts source_commit is an ancestor of the private main and that '
|
|
117
|
+
+ 'no secret/topology literal reached these files.',
|
|
118
|
+
generator: 'scripts/public-mirror-export.js',
|
|
119
|
+
source_commit: sourceCommit,
|
|
120
|
+
source_committed_at: committedAtIso,
|
|
121
|
+
lag_days: lagDays,
|
|
122
|
+
exported_files: fileCount,
|
|
123
|
+
exported_at: nowIso,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ---- git plumbing (private repo = REPO_ROOT) ------------------------------
|
|
128
|
+
function gitRoot(args) {
|
|
129
|
+
return execFileSync('git', ['-C', REPO_ROOT, ...args], { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });
|
|
130
|
+
}
|
|
131
|
+
function gitRootBuf(args) {
|
|
132
|
+
return execFileSync('git', ['-C', REPO_ROOT, ...args], { maxBuffer: 256 * 1024 * 1024 });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Newest-first [{sha, epoch}] for a ref.
|
|
136
|
+
function listCommits(ref) {
|
|
137
|
+
const out = gitRoot(['log', ref, '--format=%H %ct', '--no-merges']);
|
|
138
|
+
return out.split('\n').filter(Boolean).map((l) => {
|
|
139
|
+
const sp = l.indexOf(' ');
|
|
140
|
+
return { sha: l.slice(0, sp), epoch: Number(l.slice(sp + 1)) };
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function main() {
|
|
145
|
+
const repoDir = arg('--repo-dir');
|
|
146
|
+
const doPush = hasFlag('--push');
|
|
147
|
+
const lagDays = Number(arg('--lag-days', String(DEFAULT_LAG_DAYS)));
|
|
148
|
+
const sourceRef = arg('--source-ref', 'origin/main');
|
|
149
|
+
const dropletIp = arg('--droplet-ip', process.env.DROPLET_IP || null);
|
|
150
|
+
|
|
151
|
+
if (!repoDir) {
|
|
152
|
+
console.error('usage: node scripts/public-mirror-export.js --repo-dir <mirror-checkout> [--push] [--lag-days 180] [--source-ref origin/main]');
|
|
153
|
+
process.exit(2);
|
|
154
|
+
}
|
|
155
|
+
const mirrorDir = path.resolve(repoDir);
|
|
156
|
+
if (!fs.existsSync(path.join(mirrorDir, '.git'))) {
|
|
157
|
+
console.error(`refusing: ${mirrorDir} is not a git checkout (no .git). Clone the public mirror first.`);
|
|
158
|
+
process.exit(2);
|
|
159
|
+
}
|
|
160
|
+
if (mirrorDir === REPO_ROOT) {
|
|
161
|
+
console.error('refusing: --repo-dir is the private source repo itself. It must be the SEPARATE public mirror checkout.');
|
|
162
|
+
process.exit(2);
|
|
163
|
+
}
|
|
164
|
+
if (!Number.isFinite(lagDays) || lagDays < 1) {
|
|
165
|
+
console.error(`refusing: --lag-days must be a positive number (got ${lagDays}).`);
|
|
166
|
+
process.exit(2);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// 1. Pick the lagged snapshot commit.
|
|
170
|
+
const nowMs = Date.now();
|
|
171
|
+
const commits = listCommits(sourceRef);
|
|
172
|
+
const snapshot = pickSnapshotCommit(commits, nowMs, lagDays);
|
|
173
|
+
if (!snapshot) {
|
|
174
|
+
console.error(`[public-mirror-export] no commit on ${sourceRef} is >= ${lagDays} days old yet — nothing to publish. (Repo younger than the publish lag.)`);
|
|
175
|
+
process.exit(0);
|
|
176
|
+
}
|
|
177
|
+
const committedAtIso = new Date(snapshot.epoch * 1000).toISOString();
|
|
178
|
+
console.error(`[public-mirror-export] snapshot = ${snapshot.sha.slice(0, 12)} (committed ${committedAtIso}, ${lagDays}d lag) from ${sourceRef}`);
|
|
179
|
+
|
|
180
|
+
// 2. Enumerate + partition the tree through the manifest (single source of truth).
|
|
181
|
+
const entries = parseLsTree(gitRoot(['ls-tree', '-r', snapshot.sha])).filter((e) => e.type === 'blob');
|
|
182
|
+
const publishable = entries.filter((e) => isPublishable(e.path));
|
|
183
|
+
console.error(`[public-mirror-export] tree has ${entries.length} files; ${publishable.length} publishable per the manifest, ${entries.length - publishable.length} excluded.`);
|
|
184
|
+
if (publishable.length === 0) {
|
|
185
|
+
console.error('refusing: the publishable set is EMPTY — that is almost certainly a bug (manifest/ref mismatch), not an intentional wipe. Aborting without touching the mirror.');
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 3. Build the redaction rules from THIS instance's branding (current HEAD), plus the
|
|
190
|
+
// droplet IP as an exact extra literal (sourced here, never written to a file).
|
|
191
|
+
let branding = {};
|
|
192
|
+
try {
|
|
193
|
+
branding = JSON.parse(fs.readFileSync(path.join(REPO_ROOT, 'config/branding.json'), 'utf8'));
|
|
194
|
+
} catch { /* vanilla instance: derive only from the public-IP floor */ }
|
|
195
|
+
// Owner-identity aliases beyond the GitHub login (real name, home-dir username) come
|
|
196
|
+
// from OWNER_ALIASES (comma-separated) — set in the WORKFLOW yaml, which is excluded
|
|
197
|
+
// from the mirror, so the alias literal never appears in a published file. Redacting
|
|
198
|
+
// the login/alias substring also covers "/Users/<login>" home paths.
|
|
199
|
+
const ownerAliases = String(process.env.OWNER_ALIASES || '')
|
|
200
|
+
.split(',').map((s) => s.trim()).filter(Boolean);
|
|
201
|
+
const extra = { owners: ownerAliases, literals: dropletIp ? [dropletIp] : [] };
|
|
202
|
+
const rules = buildRedactionRules(branding, extra);
|
|
203
|
+
const sensitiveLiterals = collectSensitiveLiterals(branding, extra);
|
|
204
|
+
const envSecrets = collectEnvSecrets();
|
|
205
|
+
console.error(`[public-mirror-export] ${rules.length} redaction rule(s), ${sensitiveLiterals.length} gate literal(s) + public-IP floor + ${envSecrets.length} env-secret literal(s).`);
|
|
206
|
+
|
|
207
|
+
// 4. Redact every file IN MEMORY and run the fail-closed no-leak gate. Nothing touches
|
|
208
|
+
// the mirror filesystem until the ENTIRE set is proven clean (atomic abort).
|
|
209
|
+
const staged = []; // { path, buf, mode }
|
|
210
|
+
const leaks = []; // { path, label, sample? }
|
|
211
|
+
for (const e of publishable) {
|
|
212
|
+
let raw;
|
|
213
|
+
try {
|
|
214
|
+
raw = gitRootBuf(['cat-file', 'blob', e.sha]);
|
|
215
|
+
} catch (err) {
|
|
216
|
+
leaks.push({ path: e.path, label: `read-failed:${err.message}` });
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
const { buf, leaks: fileLeaks, secret } = redactBlob({ buf: raw, rules, sensitiveLiterals, envSecrets });
|
|
220
|
+
for (const l of fileLeaks) leaks.push({ path: e.path, label: l.label, sample: l.sample });
|
|
221
|
+
if (secret) leaks.push({ path: e.path, label: 'secret-shape' }); // never print the secret sample
|
|
222
|
+
staged.push({ path: e.path, buf, mode: e.mode });
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (leaks.length > 0) {
|
|
226
|
+
console.error(`\n[public-mirror-export] NO-LEAK GATE FAILED — ${leaks.length} residual leak(s). PUBLISHING NOTHING (fail-closed):`);
|
|
227
|
+
for (const l of leaks.slice(0, 50)) {
|
|
228
|
+
// Print the label + file but NEVER a secret value; instance literals are safe to show.
|
|
229
|
+
const shown = l.label === 'secret-shape' ? '' : (l.sample ? ` (“${String(l.sample).slice(0, 40)}”)` : '');
|
|
230
|
+
console.error(` ${l.path}: ${l.label}${shown}`);
|
|
231
|
+
}
|
|
232
|
+
if (leaks.length > 50) console.error(` … +${leaks.length - 50} more`);
|
|
233
|
+
console.error('\nFix: extend the redaction rules (scripts/gds/mirror-redact.js) or the manifest exclusions (scripts/gds/publish-manifest.js), then re-run. The mirror was NOT modified.');
|
|
234
|
+
process.exit(1);
|
|
235
|
+
}
|
|
236
|
+
console.error(`[public-mirror-export] no-leak gate PASSED — ${staged.length} files clean.`);
|
|
237
|
+
|
|
238
|
+
// 5. Clean → write → provenance. Only reached when the whole set is clean.
|
|
239
|
+
clearMirrorTree(mirrorDir);
|
|
240
|
+
for (const f of staged) {
|
|
241
|
+
const dest = path.join(mirrorDir, f.path);
|
|
242
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
243
|
+
fs.writeFileSync(dest, f.buf);
|
|
244
|
+
if (f.mode === '100755') fs.chmodSync(dest, 0o755); // preserve the executable bit
|
|
245
|
+
}
|
|
246
|
+
const provenance = buildProvenance({
|
|
247
|
+
sourceCommit: snapshot.sha,
|
|
248
|
+
committedAtIso,
|
|
249
|
+
lagDays,
|
|
250
|
+
fileCount: staged.length,
|
|
251
|
+
nowIso: new Date(nowMs).toISOString(),
|
|
252
|
+
});
|
|
253
|
+
fs.writeFileSync(path.join(mirrorDir, PROVENANCE_FILE), JSON.stringify(provenance, null, 2) + '\n');
|
|
254
|
+
|
|
255
|
+
// 6. Commit + (optionally) push.
|
|
256
|
+
const mgit = (args) => execFileSync('git', ['-C', mirrorDir, ...args], { encoding: 'utf8' });
|
|
257
|
+
mgit(['add', '-A']);
|
|
258
|
+
const status = mgit(['status', '--porcelain']);
|
|
259
|
+
if (!status.trim()) {
|
|
260
|
+
console.error('[public-mirror-export] mirror already up to date for this snapshot — nothing to commit.');
|
|
261
|
+
process.exit(0);
|
|
262
|
+
}
|
|
263
|
+
console.error(`[public-mirror-export] ${status.split('\n').filter(Boolean).length} path(s) changed in the mirror.`);
|
|
264
|
+
if (!doPush) {
|
|
265
|
+
console.error('[public-mirror-export] DRY RUN (no --push). Redacted tree written + gated clean; review the checkout, then re-run with --push.');
|
|
266
|
+
process.exit(0);
|
|
267
|
+
}
|
|
268
|
+
// Commit message carries only the SHA + date (no instance literals/secrets).
|
|
269
|
+
mgit(['commit', '-m', `chore(mirror): redacted snapshot of ${snapshot.sha.slice(0, 12)} (committed ${committedAtIso}; ${lagDays}d lag)`]);
|
|
270
|
+
mgit(['push', 'origin', 'HEAD:main']);
|
|
271
|
+
console.error('[public-mirror-export] published to the public mirror.');
|
|
272
|
+
process.exit(0);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Remove every tracked + untracked entry from the mirror working tree EXCEPT .git, so a
|
|
276
|
+
// file that drops out of the publishable set (or out of the lagged tree) disappears from
|
|
277
|
+
// the mirror too. Only reached after the no-leak gate passes, so this never wipes the
|
|
278
|
+
// mirror on a failed run.
|
|
279
|
+
function clearMirrorTree(mirrorDir) {
|
|
280
|
+
for (const name of fs.readdirSync(mirrorDir)) {
|
|
281
|
+
if (name === '.git') continue;
|
|
282
|
+
fs.rmSync(path.join(mirrorDir, name), { recursive: true, force: true });
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
module.exports = {
|
|
287
|
+
pickSnapshotCommit, parseLsTree, isBinary, redactBlob, buildProvenance,
|
|
288
|
+
PROVENANCE_FILE, DEFAULT_LAG_DAYS,
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
if (require.main === module) main();
|