@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,291 @@
|
|
|
1
|
+
// src/module-seams.js — the kernel seam registry (the switchboard).
|
|
2
|
+
//
|
|
3
|
+
// The module system's one-way rule (ADR 0083 / design 04§1) forbids a module
|
|
4
|
+
// importing another module. But modules still need to cooperate: the lifecycle
|
|
5
|
+
// (which ships a task) needs a reward figure the economy module computes; the
|
|
6
|
+
// lifecycle emits `task.shipped` and the discord module may want to react. The
|
|
7
|
+
// resolution is a KERNEL-MEDIATED SEAM — the kernel is a switchboard so no
|
|
8
|
+
// module ever holds a reference to another:
|
|
9
|
+
//
|
|
10
|
+
// • PORTS (a required capability): a provider module registers a named
|
|
11
|
+
// provider; a consumer asks the kernel to resolve it and calls it. Exactly
|
|
12
|
+
// one provider per port (it is a required capability, not a broadcast).
|
|
13
|
+
// resolve() on an unregistered port THROWS (fail-clear) — a missing required
|
|
14
|
+
// capability is a configuration error, not a silent no-op.
|
|
15
|
+
//
|
|
16
|
+
// • EVENTS (an optional reaction): a module emits a named event with a
|
|
17
|
+
// payload; zero-or-more modules that registered a listener react. emit()
|
|
18
|
+
// ISOLATES listener errors — one bad listener never breaks the emitter or
|
|
19
|
+
// the other listeners.
|
|
20
|
+
//
|
|
21
|
+
// This file is the minimal, correct implementation introduced with the doorway
|
|
22
|
+
// (BV1.R37 / task 1406). The hardening pass (BV1.R39 / task 1408, M05) adds the
|
|
23
|
+
// required-vs-optional port distinction wired to the loader, introspection, and
|
|
24
|
+
// the full hermetic test matrix. It is re-exported through src/module-api.js so
|
|
25
|
+
// a module reaches it only via the published doorway.
|
|
26
|
+
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Ports (required, single-provider capabilities)
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
const providers = new Map(); // portName -> provider value/function
|
|
32
|
+
|
|
33
|
+
// Register a provider for a named port. Throws on a duplicate registration —
|
|
34
|
+
// a port is a single, required capability; two providers is a wiring bug, not a
|
|
35
|
+
// last-write-wins situation. (The loader catches this and fails the affected
|
|
36
|
+
// module's mount, never the whole boot.)
|
|
37
|
+
function registerProvider(portName, provider) {
|
|
38
|
+
if (typeof portName !== 'string' || !portName) {
|
|
39
|
+
throw new TypeError('registerProvider(portName, provider): portName must be a non-empty string');
|
|
40
|
+
}
|
|
41
|
+
if (provider == null) {
|
|
42
|
+
throw new TypeError(`registerProvider("${portName}"): provider must not be null/undefined`);
|
|
43
|
+
}
|
|
44
|
+
if (providers.has(portName)) {
|
|
45
|
+
throw new Error(`seam: port "${portName}" already has a provider (a port is single-provider)`);
|
|
46
|
+
}
|
|
47
|
+
providers.set(portName, provider);
|
|
48
|
+
return provider;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// True if a provider is registered for the port.
|
|
52
|
+
function hasProvider(portName) {
|
|
53
|
+
return providers.has(portName);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Resolve a port to its provider. Throws if none is registered — a required
|
|
57
|
+
// capability that nobody provides is a fail-closed error, surfaced clearly.
|
|
58
|
+
function resolve(portName) {
|
|
59
|
+
if (!providers.has(portName)) {
|
|
60
|
+
throw new Error(`seam: no provider registered for required port "${portName}"`);
|
|
61
|
+
}
|
|
62
|
+
return providers.get(portName);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Optional resolution — returns the provider or `fallback` (default null) with
|
|
66
|
+
// no throw. For consumers that can degrade when a capability is absent.
|
|
67
|
+
function resolveOptional(portName, fallback = null) {
|
|
68
|
+
return providers.has(portName) ? providers.get(portName) : fallback;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Names of all registered ports (introspection / drift scans).
|
|
72
|
+
function listPorts() {
|
|
73
|
+
return Array.from(providers.keys()).sort();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// BOOT-TIME (manifest-level) verification, distinct from resolve()'s RUNTIME
|
|
77
|
+
// throw: given the ENABLED modules' manifests, confirm every consumed port is
|
|
78
|
+
// provided by some enabled module, and no port has two providers. The loader
|
|
79
|
+
// (BV1.R41) runs this before mounting so a required capability with no provider
|
|
80
|
+
// is caught at boot with a clear message — not as a surprise throw the first time
|
|
81
|
+
// the seam is used. Pure (no registry mutation), so it is safe to run anytime.
|
|
82
|
+
// manifests: [{ key, provides: [...], consumes: [...] }] → { ok, errors: [...] }.
|
|
83
|
+
function verifyPortsSatisfied(manifests = []) {
|
|
84
|
+
const provided = new Map(); // port -> [providerKey,...]
|
|
85
|
+
for (const m of manifests) {
|
|
86
|
+
for (const p of m.provides || []) {
|
|
87
|
+
if (!provided.has(p)) provided.set(p, []);
|
|
88
|
+
provided.get(p).push(m.key);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const errors = [];
|
|
92
|
+
for (const m of manifests) {
|
|
93
|
+
for (const c of m.consumes || []) {
|
|
94
|
+
if (!provided.has(c)) {
|
|
95
|
+
errors.push(`module "${m.key}" consumes port "${c}" but no enabled module provides it`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
for (const [port, keys] of provided) {
|
|
100
|
+
if (keys.length > 1) errors.push(`port "${port}" is provided by more than one enabled module: ${keys.join(', ')} (a port is single-provider)`);
|
|
101
|
+
}
|
|
102
|
+
return { ok: errors.length === 0, errors };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
// Events (optional, many-listener reactions)
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
|
|
109
|
+
const listeners = new Map(); // eventName -> Set<fn>
|
|
110
|
+
|
|
111
|
+
// Subscribe to an event. Returns an unsubscribe function.
|
|
112
|
+
function on(eventName, handler) {
|
|
113
|
+
if (typeof eventName !== 'string' || !eventName) {
|
|
114
|
+
throw new TypeError('on(eventName, handler): eventName must be a non-empty string');
|
|
115
|
+
}
|
|
116
|
+
if (typeof handler !== 'function') {
|
|
117
|
+
throw new TypeError(`on("${eventName}"): handler must be a function`);
|
|
118
|
+
}
|
|
119
|
+
if (!listeners.has(eventName)) listeners.set(eventName, new Set());
|
|
120
|
+
listeners.get(eventName).add(handler);
|
|
121
|
+
return function off() {
|
|
122
|
+
const set = listeners.get(eventName);
|
|
123
|
+
if (set) set.delete(handler);
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Emit an event to all listeners. Listener errors are ISOLATED: a throwing
|
|
128
|
+
// listener is logged and skipped; the emitter and the remaining listeners are
|
|
129
|
+
// unaffected. Returns the number of listeners invoked.
|
|
130
|
+
function emit(eventName, payload) {
|
|
131
|
+
const set = listeners.get(eventName);
|
|
132
|
+
if (!set || set.size === 0) return 0;
|
|
133
|
+
let invoked = 0;
|
|
134
|
+
for (const handler of set) {
|
|
135
|
+
invoked += 1; // count every listener invoked, throw or not
|
|
136
|
+
try {
|
|
137
|
+
handler(payload);
|
|
138
|
+
} catch (err) {
|
|
139
|
+
// Never let a reactor break the actor. Optional reactions are best-effort.
|
|
140
|
+
console.error(`[seam] listener for "${eventName}" threw:`, err && err.message ? err.message : err);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return invoked;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Async emit — awaits async (or sync) listeners, isolating errors the same way
|
|
147
|
+
// emit() does. For an emitter that wants to know all reactions have settled
|
|
148
|
+
// (e.g. flush a notification before returning). Returns the count invoked.
|
|
149
|
+
async function emitAsync(eventName, payload) {
|
|
150
|
+
const set = listeners.get(eventName);
|
|
151
|
+
if (!set || set.size === 0) return 0;
|
|
152
|
+
let invoked = 0;
|
|
153
|
+
for (const handler of set) {
|
|
154
|
+
invoked += 1;
|
|
155
|
+
try {
|
|
156
|
+
await handler(payload);
|
|
157
|
+
} catch (err) {
|
|
158
|
+
console.error(`[seam] async listener for "${eventName}" threw:`, err && err.message ? err.message : err);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return invoked;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Names of all events with at least one listener (introspection).
|
|
165
|
+
function listEvents() {
|
|
166
|
+
return Array.from(listeners.keys()).filter((k) => listeners.get(k).size > 0).sort();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
// Contributions (optional, many-contributor accumulating extension points)
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
//
|
|
173
|
+
// The third seam primitive, distinct from both ports and events (BV1.R42 / task
|
|
174
|
+
// 1411). A PORT is exactly one provider (a required capability); an EVENT is a
|
|
175
|
+
// fire-and-forget reaction; a CONTRIBUTION accumulates — zero-or-more modules
|
|
176
|
+
// each add a piece to a named extension point, and the kernel hands the whole
|
|
177
|
+
// set back to a core consumer that renders them together. This is how a module
|
|
178
|
+
// adds its own slice to a core surface without core hardcoding it: dev-box adds
|
|
179
|
+
// box fields + a box settings panel, discord adds its link state, art adds its
|
|
180
|
+
// key surface — each `contribute()`s; core merges. The strangler prerequisite
|
|
181
|
+
// that lets those modules leave core (the surfaces in src/bongos/routes/me.js +
|
|
182
|
+
// modules/hall-ui/public/settings.js stop being hardcoded). With no module enabled the
|
|
183
|
+
// registry is empty and every consumer renders exactly what it does today.
|
|
184
|
+
//
|
|
185
|
+
// Canonical extension points (the names core consumes):
|
|
186
|
+
// • 'profile.fields' — server-side: each contributor is `async (ctx) => ({…slice})`;
|
|
187
|
+
// the slices merge into the GET /api/gds/me payload.
|
|
188
|
+
// (The client settings-panel seam is its browser twin,
|
|
189
|
+
// window.OTB.contributeSettingsPanel in dom-utils.js.)
|
|
190
|
+
|
|
191
|
+
const contributors = new Map(); // point -> [contribution, ...] (registration order)
|
|
192
|
+
|
|
193
|
+
// Register a contribution to a named extension point. Unlike a port, a point
|
|
194
|
+
// accepts MANY contributions (no duplicate-registration throw). Returns the
|
|
195
|
+
// contribution so a caller can keep a handle.
|
|
196
|
+
function contribute(point, contribution) {
|
|
197
|
+
if (typeof point !== 'string' || !point) {
|
|
198
|
+
throw new TypeError('contribute(point, contribution): point must be a non-empty string');
|
|
199
|
+
}
|
|
200
|
+
if (contribution == null) {
|
|
201
|
+
throw new TypeError(`contribute("${point}"): contribution must not be null/undefined`);
|
|
202
|
+
}
|
|
203
|
+
if (!contributors.has(point)) contributors.set(point, []);
|
|
204
|
+
contributors.get(point).push(contribution);
|
|
205
|
+
return contribution;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// All contributions registered for a point, in registration order. Returns a
|
|
209
|
+
// COPY (never the live array) and [] for an unknown point — a consumer can
|
|
210
|
+
// always iterate without a guard.
|
|
211
|
+
function contributions(point) {
|
|
212
|
+
return contributors.has(point) ? contributors.get(point).slice() : [];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Collect every function-contribution to a point: invoke it with `ctx`, await
|
|
216
|
+
// the result, and return the array of non-nullish results. For accumulating
|
|
217
|
+
// server-side points like 'profile.fields' where each contributor is
|
|
218
|
+
// `async (ctx) => ({…slice})`. Errors are ISOLATED the same way emit() isolates
|
|
219
|
+
// a listener — one throwing contributor is logged and skipped, never breaking
|
|
220
|
+
// the others or the caller. A non-function contribution is returned as-is.
|
|
221
|
+
async function collectContributions(point, ctx) {
|
|
222
|
+
const out = [];
|
|
223
|
+
for (const c of contributions(point)) {
|
|
224
|
+
try {
|
|
225
|
+
const v = typeof c === 'function' ? await c(ctx) : c;
|
|
226
|
+
if (v != null) out.push(v);
|
|
227
|
+
} catch (err) {
|
|
228
|
+
console.error(`[seam] contribution to "${point}" threw:`, err && err.message ? err.message : err);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return out;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Merge accumulating contribution slices into a base object, ADD-ONLY: a slice
|
|
235
|
+
// may introduce new keys but never overwrite one already on `base` (core wins —
|
|
236
|
+
// a module's contribution can't clobber a core field). Mutates + returns `base`,
|
|
237
|
+
// and reports any collided keys so the caller can surface them — that signals a
|
|
238
|
+
// move task took over a core key without first removing the core copy. Used by
|
|
239
|
+
// GET /api/gds/me to fold 'profile.fields' slices into the profile payload.
|
|
240
|
+
function mergeContributions(base, slices) {
|
|
241
|
+
const collisions = [];
|
|
242
|
+
for (const slice of slices || []) {
|
|
243
|
+
if (!slice || typeof slice !== 'object') continue;
|
|
244
|
+
for (const [k, v] of Object.entries(slice)) {
|
|
245
|
+
if (Object.prototype.hasOwnProperty.call(base, k)) { collisions.push(k); continue; }
|
|
246
|
+
base[k] = v;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return { base, collisions };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Names of all extension points with at least one contribution (introspection).
|
|
253
|
+
function listContributionPoints() {
|
|
254
|
+
return Array.from(contributors.keys()).filter((k) => contributors.get(k).length > 0).sort();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// A snapshot of the wired seams — for an observability tile / drift scan.
|
|
258
|
+
function snapshot() {
|
|
259
|
+
return {
|
|
260
|
+
ports: listPorts(),
|
|
261
|
+
events: listEvents().map((e) => ({ event: e, listeners: listeners.get(e).size })),
|
|
262
|
+
contributions: listContributionPoints().map((p) => ({ point: p, contributors: contributors.get(p).length })),
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Test-only reset (kept tiny + explicit so hermetic tests start clean).
|
|
267
|
+
function _reset() {
|
|
268
|
+
providers.clear();
|
|
269
|
+
listeners.clear();
|
|
270
|
+
contributors.clear();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
module.exports = {
|
|
274
|
+
registerProvider,
|
|
275
|
+
hasProvider,
|
|
276
|
+
resolve,
|
|
277
|
+
resolveOptional,
|
|
278
|
+
listPorts,
|
|
279
|
+
verifyPortsSatisfied,
|
|
280
|
+
on,
|
|
281
|
+
emit,
|
|
282
|
+
emitAsync,
|
|
283
|
+
listEvents,
|
|
284
|
+
contribute,
|
|
285
|
+
contributions,
|
|
286
|
+
collectContributions,
|
|
287
|
+
mergeContributions,
|
|
288
|
+
listContributionPoints,
|
|
289
|
+
snapshot,
|
|
290
|
+
_reset,
|
|
291
|
+
};
|
package/src/modules.js
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
// src/modules.js — the feature-module selection layer (R54, task 1193, ADR 0062 §4).
|
|
2
|
+
//
|
|
3
|
+
// A config-flag layer that gates OPTIONAL features per instance. Branding
|
|
4
|
+
// (src/branding.js) answers "what does this instance look like?"; this answers
|
|
5
|
+
// "what does this instance DO?" — which optional features mount their routes,
|
|
6
|
+
// hall/status UI sections, skills, disciplines, Colyseus rooms, and pollers.
|
|
7
|
+
//
|
|
8
|
+
// The cut: a small CORE is always on (the methodology — builders, tasks,
|
|
9
|
+
// claims, credits, grading, memory, recall — everything a build platform needs
|
|
10
|
+
// to build itself). Everything beyond that is a MODULE an instance turns on.
|
|
11
|
+
//
|
|
12
|
+
// Resolution precedence (highest wins), mirroring src/branding.js:
|
|
13
|
+
// env override -> instance config (config/modules.json) -> neutral
|
|
14
|
+
// starter (config/modules.neutral.json)
|
|
15
|
+
// A fresh instance with NO config resolves to the VANILLA set: every feature
|
|
16
|
+
// module OFF (fail-to-vanilla, never fail-to-OTB); disciplines are core only
|
|
17
|
+
// (engineer + ideator — artist rides the art-pipeline module, R59).
|
|
18
|
+
//
|
|
19
|
+
// This is a config-flag exclusion mechanism, NOT a full plugin registry — the
|
|
20
|
+
// cheaper near-term shape (ADR 0062 §4). R59 (task 1198) moves game + art-pipeline
|
|
21
|
+
// in; R60 (task 1199) moves discord + dev-box in (UI sections / skills / pollers);
|
|
22
|
+
// they consume the registry declared here.
|
|
23
|
+
|
|
24
|
+
const fs = require('node:fs');
|
|
25
|
+
const path = require('node:path');
|
|
26
|
+
// The loader opens the closed registry: it discovers modules/*/module.json so the
|
|
27
|
+
// resolver below spans built-in + discovered modules (ADR 0083 / BV1.R41). Empty
|
|
28
|
+
// until a module is moved into modules/ — so this is a no-op on the current tree.
|
|
29
|
+
const loader = require('./module-loader/loader');
|
|
30
|
+
const { resolveCoreRoot, resolveInstanceRoot } = require('./instance-config');
|
|
31
|
+
|
|
32
|
+
// ADR 0108 §1: the neutral starter ships WITH the core package; the instance
|
|
33
|
+
// pack is host content. Both resolvers return the repo root today, so this is
|
|
34
|
+
// byte-identical for the live instance.
|
|
35
|
+
const NEUTRAL_PATH = path.join(resolveCoreRoot(), 'config', 'modules.neutral.json');
|
|
36
|
+
const INSTANCE_PATH = path.join(resolveInstanceRoot(), 'config', 'modules.json');
|
|
37
|
+
|
|
38
|
+
// The module registry — the single declarative source of what each optional
|
|
39
|
+
// module contributes. The `contributes` map is documentation + the surface
|
|
40
|
+
// R59/R60 consume to mount/teardown a module's parts. `default` is the
|
|
41
|
+
// fail-safe value when neither config nor env names the module: always false,
|
|
42
|
+
// so a brand-new instance is vanilla.
|
|
43
|
+
//
|
|
44
|
+
// CORE (always on, never a module): auth, builders, tasks, claims, versions,
|
|
45
|
+
// done-when, credits/cost, inbox, blockers, leaderboard, analytics,
|
|
46
|
+
// audit-log, security, access-requests, sessions, gate-approvals, healthz,
|
|
47
|
+
// public. These mount unconditionally. The four optional feature modules AND the
|
|
48
|
+
// first TWO carved CORE-domain modules have graduated to modules/<key>/ (dev-box
|
|
49
|
+
// BV1.R43, discord BV1.R47, art-pipeline BV1.R48, game BV1.R49, memory BV1.R72 —
|
|
50
|
+
// memory/recall/search/learnings, ADR 0091 §2 — and grading BV1.R73 — the
|
|
51
|
+
// adversarial grade panel + rubric, behind the `grade` kernel port, ADR 0091 §4).
|
|
52
|
+
// A core-domain module like memory or grading is `default: true` (it ships to
|
|
53
|
+
// every instance — the build system's memory + quality gate are not optional),
|
|
54
|
+
// unlike the default-off feature modules.
|
|
55
|
+
// The built-in registry is now empty; every module is discovered + mounted by
|
|
56
|
+
// moduleLoader from modules/*/module.json.
|
|
57
|
+
const MODULE_REGISTRY = {};
|
|
58
|
+
|
|
59
|
+
// Disciplines the CORE always provides. Modules add to this (e.g. art-pipeline
|
|
60
|
+
// adds 'artist'). Ideation is methodology core — the idea_inbox, capture.js and
|
|
61
|
+
// /idea-triage ship to every instance regardless of feature modules — so a
|
|
62
|
+
// vanilla instance offers engineer + ideator. Only 'artist' is module-gated: it
|
|
63
|
+
// exists to produce the game's pixel art, so it rides the art-pipeline module
|
|
64
|
+
// (R59 / task 1198). A vanilla instance therefore offers ['engineer','ideator'].
|
|
65
|
+
const CORE_DISCIPLINES = ['engineer', 'ideator'];
|
|
66
|
+
|
|
67
|
+
const KNOWN_MODULES = Object.keys(MODULE_REGISTRY);
|
|
68
|
+
|
|
69
|
+
// The EFFECTIVE registry spans the built-in MODULE_REGISTRY + every module
|
|
70
|
+
// discovered under modules/ (ADR 0083 / BV1.R41). As a built-in is moved out
|
|
71
|
+
// into modules/<key>/ (BV1.R43+), it leaves MODULE_REGISTRY and reappears here
|
|
72
|
+
// as a discovered manifest, so membership is unchanged across the move. With no
|
|
73
|
+
// modules/ dir (the current tree) discoveredRegistry() is {} → effectiveRegistry
|
|
74
|
+
// === MODULE_REGISTRY and knownModules() === KNOWN_MODULES (byte-identical).
|
|
75
|
+
function effectiveRegistry() {
|
|
76
|
+
return { ...MODULE_REGISTRY, ...loader.discoveredRegistry() };
|
|
77
|
+
}
|
|
78
|
+
function knownModules() {
|
|
79
|
+
return Object.keys(effectiveRegistry());
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const TRUTHY = new Set(['1', 'true', 'on', 'yes', 'enabled']);
|
|
83
|
+
const FALSY = new Set(['0', 'false', 'off', 'no', 'disabled']);
|
|
84
|
+
|
|
85
|
+
const isObj = (v) => v && typeof v === 'object' && !Array.isArray(v);
|
|
86
|
+
|
|
87
|
+
function coerceBool(v) {
|
|
88
|
+
if (typeof v === 'boolean') return v;
|
|
89
|
+
if (typeof v === 'string') {
|
|
90
|
+
const s = v.trim().toLowerCase();
|
|
91
|
+
if (TRUTHY.has(s)) return true;
|
|
92
|
+
if (FALSY.has(s)) return false;
|
|
93
|
+
}
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Pure resolver — all inputs injected, so tests drive it with zero I/O.
|
|
98
|
+
// Returns a frozen { <moduleKey>: boolean } covering EVERY registry key, plus a
|
|
99
|
+
// non-enumerable resolution that throws on an unknown module key (typo guard).
|
|
100
|
+
function resolveModules({ neutral = {}, instance = {}, env = {}, envPrefix = 'CLOUDBONGOS', registry = MODULE_REGISTRY } = {}) {
|
|
101
|
+
// The known-key set + defaults come from the passed registry: callers inject
|
|
102
|
+
// the built-in MODULE_REGISTRY (the default, what the pure unit tests use) or
|
|
103
|
+
// the effective built-in+discovered registry (what loadModules passes). This
|
|
104
|
+
// keeps resolveModules pure while letting the disk loader span discovered
|
|
105
|
+
// modules. (ADR 0083 / BV1.R41.)
|
|
106
|
+
const known = Object.keys(registry);
|
|
107
|
+
const fromConfig = (cfg, source) => {
|
|
108
|
+
const m = isObj(cfg) ? cfg.modules : undefined;
|
|
109
|
+
if (m === undefined) return {};
|
|
110
|
+
if (!isObj(m)) throw new Error(`modules: \`modules\` in ${source} config must be an object`);
|
|
111
|
+
const out = {};
|
|
112
|
+
for (const [k, v] of Object.entries(m)) {
|
|
113
|
+
if (known.includes(k)) { out[k] = v; continue; }
|
|
114
|
+
// Unknown key. A config may name a module this build hasn't installed: a stripped
|
|
115
|
+
// CORE has no game/art-pipeline/discord/dev-box, yet config/modules.neutral.json
|
|
116
|
+
// (which ships WITH the core) names them so the SAME file is valid in the full repo
|
|
117
|
+
// too. Tolerate an unknown module ONLY when it is DISABLED — a disabled-and-absent
|
|
118
|
+
// module is a no-op. ENABLING an absent module is a real error (the feature you asked
|
|
119
|
+
// for isn't here) and still throws, which also keeps the typo guard for the dangerous
|
|
120
|
+
// direction. (task 1824: this is what lets the vanilla core boot instead of crashing
|
|
121
|
+
// on `unknown module "game"`.)
|
|
122
|
+
if (coerceBool(v) === true) {
|
|
123
|
+
throw new Error(`modules: cannot enable unknown module "${k}" in ${source} config — it is not installed (known: ${known.join(', ') || '(none)'}).`);
|
|
124
|
+
}
|
|
125
|
+
// disabled-and-absent → silently drop (a typo on a disable is harmless; the module's
|
|
126
|
+
// default is already off, so the resolved set is identical either way).
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const merged = { ...fromConfig(neutral, 'neutral'), ...fromConfig(instance, 'instance') };
|
|
132
|
+
|
|
133
|
+
// Env overrides: <PREFIX>_MODULE_<KEY> where KEY is upper-snake of the module
|
|
134
|
+
// name (dev-box -> DEV_BOX). Highest precedence.
|
|
135
|
+
for (const key of known) {
|
|
136
|
+
const envName = `${envPrefix}_MODULE_${key.toUpperCase().replace(/-/g, '_')}`;
|
|
137
|
+
const raw = env[envName];
|
|
138
|
+
if (raw !== undefined && raw !== '') {
|
|
139
|
+
const b = coerceBool(raw);
|
|
140
|
+
if (b === undefined) throw new Error(`modules: ${envName}="${raw}" is not a boolean (use 1/0, on/off, true/false)`);
|
|
141
|
+
merged[key] = b;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const resolved = {};
|
|
146
|
+
for (const key of known) {
|
|
147
|
+
const v = key in merged ? coerceBool(merged[key]) : undefined;
|
|
148
|
+
resolved[key] = v === undefined ? registry[key].default : v;
|
|
149
|
+
}
|
|
150
|
+
return Object.freeze(resolved);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function readJson(p) {
|
|
154
|
+
try { return JSON.parse(fs.readFileSync(p, 'utf8')); }
|
|
155
|
+
catch (e) { if (e.code === 'ENOENT') return null; throw e; }
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Disk loader with the documented precedence. Both files are OPTIONAL: with
|
|
159
|
+
// neither, every module resolves to its `default` (vanilla = all off).
|
|
160
|
+
//
|
|
161
|
+
// Instance-pack FILE selection mirrors src/branding.js's GDS_BRANDING_FILE knob,
|
|
162
|
+
// so ONE deployed checkout can run two instances side by side (OTB on the
|
|
163
|
+
// committed config/modules.json; a vanilla Cloud Bongos process on the neutral
|
|
164
|
+
// set) differentiated only by env, with no divergent clone. Highest wins:
|
|
165
|
+
// explicit instancePath arg
|
|
166
|
+
// -> GDS_MODULES_FILE env (a path to a modules pack)
|
|
167
|
+
// -> if GDS_BRANDING_FILE is set (this process opted into a NON-default BRAND)
|
|
168
|
+
// but names no modules file: the NEUTRAL starter — a branded sibling must
|
|
169
|
+
// NOT silently inherit the default instance's config/modules.json. That was
|
|
170
|
+
// the bug that made cloudbongos.com advertise all four modules ON though it
|
|
171
|
+
// runs the vanilla brand (CB-V1 task 1, the C8 self-build proof). Per-module
|
|
172
|
+
// env overrides (<PREFIX>_MODULE_<KEY>) still apply on top, so a branded
|
|
173
|
+
// sibling can still opt a single module on.
|
|
174
|
+
// -> config/modules.json (the default OTB instance pack)
|
|
175
|
+
// Like branding's selector, these are FIXED env names (read before the resolved
|
|
176
|
+
// envPrefix is known), not <PREFIX>_ ones. A relative path resolves against the
|
|
177
|
+
// repo root.
|
|
178
|
+
function loadModules({ neutralPath = NEUTRAL_PATH, instancePath, env = process.env } = {}) {
|
|
179
|
+
const neutral = readJson(neutralPath) || {};
|
|
180
|
+
let ip = instancePath;
|
|
181
|
+
if (ip === undefined) {
|
|
182
|
+
const override = env.GDS_MODULES_FILE;
|
|
183
|
+
if (override) ip = path.resolve(resolveInstanceRoot(), override);
|
|
184
|
+
else if (env.GDS_BRANDING_FILE) ip = NEUTRAL_PATH;
|
|
185
|
+
else ip = INSTANCE_PATH;
|
|
186
|
+
}
|
|
187
|
+
const instance = readJson(ip) || {};
|
|
188
|
+
// Reuse the branding env prefix so an instance has ONE prefix, not two.
|
|
189
|
+
let envPrefix = 'CLOUDBONGOS';
|
|
190
|
+
try { envPrefix = require('./branding').branding().envPrefix || envPrefix; } catch { /* fail-to-default */ }
|
|
191
|
+
// Resolve against the EFFECTIVE registry (built-in + discovered) so a config
|
|
192
|
+
// flag for a discovered module is honored. No-op until a module exists.
|
|
193
|
+
return resolveModules({ neutral, instance, env, envPrefix, registry: effectiveRegistry() });
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Resolved singleton for app code; lazy so require-time never crashes tooling.
|
|
197
|
+
let _cached = null;
|
|
198
|
+
const modules = () => (_cached ||= loadModules());
|
|
199
|
+
// Public invalidation — call after something changes what loadModules() would
|
|
200
|
+
// read (a config-file write from the hall's Modules-tab toggle, ADR 0107 §9;
|
|
201
|
+
// also used by tests). Cheap: the next modules() call just re-reads disk.
|
|
202
|
+
const reload = () => { _cached = null; return modules(); };
|
|
203
|
+
const _resetForTests = () => { _cached = null; };
|
|
204
|
+
|
|
205
|
+
function isModuleEnabled(name, set = modules()) {
|
|
206
|
+
const known = knownModules();
|
|
207
|
+
if (!known.includes(name)) {
|
|
208
|
+
throw new Error(`modules: isModuleEnabled("${name}") — unknown module (known: ${known.join(', ')})`);
|
|
209
|
+
}
|
|
210
|
+
return set[name] === true;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const enabledModules = (set = modules()) => knownModules().filter((k) => set[k] === true);
|
|
214
|
+
|
|
215
|
+
// Disciplines this instance offers = core + every enabled module's declared
|
|
216
|
+
// disciplines, deduped, stable order. Vanilla = ['engineer','ideator'].
|
|
217
|
+
function enabledDisciplines(set = modules()) {
|
|
218
|
+
const reg = effectiveRegistry();
|
|
219
|
+
const out = [...CORE_DISCIPLINES];
|
|
220
|
+
for (const key of enabledModules(set)) {
|
|
221
|
+
for (const d of (reg[key] && reg[key].contributes.disciplines) || []) {
|
|
222
|
+
if (!out.includes(d)) out.push(d);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return out;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// CLIENT-SAFE projection — module flags are just booleans, all safe to expose.
|
|
229
|
+
// The hall/status front-ends read this to hide UI sections for off modules.
|
|
230
|
+
function clientModules(set = modules()) {
|
|
231
|
+
return {
|
|
232
|
+
enabled: knownModules().reduce((o, k) => { o[k] = set[k] === true; return o; }, {}),
|
|
233
|
+
disciplines: enabledDisciplines(set),
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
module.exports = {
|
|
238
|
+
MODULE_REGISTRY,
|
|
239
|
+
KNOWN_MODULES,
|
|
240
|
+
effectiveRegistry,
|
|
241
|
+
knownModules,
|
|
242
|
+
CORE_DISCIPLINES,
|
|
243
|
+
resolveModules,
|
|
244
|
+
loadModules,
|
|
245
|
+
modules,
|
|
246
|
+
reload,
|
|
247
|
+
isModuleEnabled,
|
|
248
|
+
enabledModules,
|
|
249
|
+
enabledDisciplines,
|
|
250
|
+
clientModules,
|
|
251
|
+
NEUTRAL_PATH,
|
|
252
|
+
INSTANCE_PATH,
|
|
253
|
+
_resetForTests,
|
|
254
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// src/platform-server.js — the GDS-ONLY entrypoint (ADR 0062 R51, task 1190).
|
|
2
|
+
//
|
|
3
|
+
// The inverse of src/preview-server.js: where the preview server boots ONLY the
|
|
4
|
+
// game, this boots ONLY the build platform (Cloud Bongos) — the GDS API + the
|
|
5
|
+
// builders' hall + the status dashboard — with NO game in the process.
|
|
6
|
+
//
|
|
7
|
+
// WHAT IT SERVES — the entire internal surface, via the shared mount that
|
|
8
|
+
// server.js also uses (so the two entrypoints never drift, ADR 0052):
|
|
9
|
+
// * /healthz + /version
|
|
10
|
+
// * /api/gds/* — the full GDS API (buildGdsRouter)
|
|
11
|
+
// * the status dashboard host — modules/status-ui/public/ (the status-ui module's
|
|
12
|
+
// web surface, BV1.R84 — served by the loader seam)
|
|
13
|
+
// * the builders' hall host — modules/hall-ui/public/ (the hall-ui module's
|
|
14
|
+
// web surface, BV1.R85 — served by its dedicated
|
|
15
|
+
// block in serve-internal)
|
|
16
|
+
// * /downloads/devbox/* — the Dev Box installer redirects
|
|
17
|
+
//
|
|
18
|
+
// WHAT IT DELIBERATELY DOES NOT CONSTRUCT — the host game runtime:
|
|
19
|
+
// * NO Colyseus server, NO WebSocketTransport
|
|
20
|
+
// * NO game rooms (WorldRoom / QueueRoom). The builders' hall is still live
|
|
21
|
+
// here: its updates ride the SSE endpoint in the GDS router
|
|
22
|
+
// (src/bongos/routes/live.js, R55/ADR 0069), which needs no Colyseus — that is
|
|
23
|
+
// exactly why the room was retired.
|
|
24
|
+
// * NO Phaser/Colyseus vendored client libs (/vendor/*)
|
|
25
|
+
// * NO tile assets (/assets/tiles/*) and NO game static (public/)
|
|
26
|
+
// Because this process never requires src/rooms/, src/world/, or colyseus, a
|
|
27
|
+
// game-less Cloud Bongos instance — one whose repo carries zero game code — can
|
|
28
|
+
// run it unchanged. The "no game route/asset is reachable" guarantee is enforced
|
|
29
|
+
// by ABSENCE (the game middleware is simply never mounted), not by a runtime
|
|
30
|
+
// check, exactly as preview-server.js enforces "no internal API" by absence.
|
|
31
|
+
//
|
|
32
|
+
// Background services (uptime poller, publish reconciler, Discord bot) are NOT
|
|
33
|
+
// started here. They are not game code, but which of them a given instance runs
|
|
34
|
+
// is an instance-policy decision that R54's feature-module system (task 1193)
|
|
35
|
+
// will own; R51 keeps this entrypoint to the minimal "serve the surfaces" core.
|
|
36
|
+
|
|
37
|
+
const http = require('http');
|
|
38
|
+
const fs = require('fs');
|
|
39
|
+
const path = require('path');
|
|
40
|
+
const express = require('express');
|
|
41
|
+
const { mountInternalSurfaces, isStatusHost, isBuildersHost, injectBrandingGlobal } = require('./bongos/serve-internal');
|
|
42
|
+
const { isApiShapedPath, apiNotFoundBody } = require('./bongos/api-path-404');
|
|
43
|
+
|
|
44
|
+
const PORT = Number(process.env.PORT) || 3000;
|
|
45
|
+
const HOST = process.env.HOST || '127.0.0.1';
|
|
46
|
+
|
|
47
|
+
// The apex landing page — a game-less instance's home (replaces the bare 404 the
|
|
48
|
+
// apex host used to serve). A deliberately MINIMAL placeholder: the mascot + a
|
|
49
|
+
// way into the Builders' Hall; the full landing is its own task. Served only on
|
|
50
|
+
// the apex host (status./builders. are handled by mountInternalSurfaces). The
|
|
51
|
+
// branding pack is injected once at boot (theme + window.__BRANDING__), exactly
|
|
52
|
+
// as the hall pages are, so the look + identity come from config, not hardcode.
|
|
53
|
+
const LANDING_DIR = path.join(__dirname, '..', 'public-landing');
|
|
54
|
+
const _landingPages = new Map(); // memoized per file; '' if absent (instance ships no landing)
|
|
55
|
+
function landingPage(file) {
|
|
56
|
+
if (!_landingPages.has(file)) {
|
|
57
|
+
let html = '';
|
|
58
|
+
try {
|
|
59
|
+
html = injectBrandingGlobal(fs.readFileSync(path.join(LANDING_DIR, file), 'utf8'));
|
|
60
|
+
} catch { /* absent → '' */ }
|
|
61
|
+
_landingPages.set(file, html);
|
|
62
|
+
}
|
|
63
|
+
return _landingPages.get(file);
|
|
64
|
+
}
|
|
65
|
+
function landingHtml() { return landingPage('index.html'); }
|
|
66
|
+
function isApexHost(req) {
|
|
67
|
+
return !isStatusHost(req) && !isBuildersHost(req);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Build the configured Express app WITHOUT binding a port — so the boot smoke
|
|
71
|
+
// test (tests/platform-boot.mjs) can drive it over an ephemeral listener and
|
|
72
|
+
// importing this module never starts a server.
|
|
73
|
+
function buildPlatformApp() {
|
|
74
|
+
const app = express();
|
|
75
|
+
app.disable('x-powered-by');
|
|
76
|
+
// A Cloud Bongos instance also sits behind a reverse proxy (Caddy/Cloudflare);
|
|
77
|
+
// trust the immediate proxy so req.secure / x-forwarded-proto are honest for
|
|
78
|
+
// the OAuth callbacks the GDS auth router performs.
|
|
79
|
+
app.set('trust proxy', 1);
|
|
80
|
+
|
|
81
|
+
// The whole internal surface — shared verbatim with server.js (ADR 0062 R51).
|
|
82
|
+
mountInternalSurfaces(app);
|
|
83
|
+
|
|
84
|
+
// Apex landing. On the apex host (not status./builders.), GET / serves the
|
|
85
|
+
// branding-injected landing page, and other paths can resolve a landing asset
|
|
86
|
+
// (e.g. the mascot image) from public-landing/. Both fall through to the 404
|
|
87
|
+
// tail when there is no landing file or no matching asset.
|
|
88
|
+
app.get('/', (req, res, next) => {
|
|
89
|
+
if (!isApexHost(req)) return next();
|
|
90
|
+
const html = landingHtml();
|
|
91
|
+
if (!html) return next();
|
|
92
|
+
res.type('html').send(html);
|
|
93
|
+
});
|
|
94
|
+
// The branded project-creation experience (goal 35, task 2081) — a sibling
|
|
95
|
+
// landing page at a clean /create URL, branding-injected like the landing.
|
|
96
|
+
app.get('/create', (req, res, next) => {
|
|
97
|
+
if (!isApexHost(req)) return next();
|
|
98
|
+
const html = landingPage('create.html');
|
|
99
|
+
if (!html) return next();
|
|
100
|
+
res.type('html').send(html);
|
|
101
|
+
});
|
|
102
|
+
const landingAssets = express.static(LANDING_DIR, { index: false, fallthrough: true });
|
|
103
|
+
app.use((req, res, next) => {
|
|
104
|
+
if (!isApexHost(req)) return next();
|
|
105
|
+
return landingAssets(req, res, next);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Non-game tail. Anything that did not resolve to /api/gds, the status host,
|
|
109
|
+
// or the builders' hall lands here. There is NO game to fall through to, so:
|
|
110
|
+
// * an API-shaped path gets a self-describing JSON 404 (never HTML), the
|
|
111
|
+
// same contract server.js gives so a mis-prefixed CLI call is legible;
|
|
112
|
+
// * everything else gets a plain-text 404 — a game-less instance ships no
|
|
113
|
+
// themed island page (public/404.html lives in the game module).
|
|
114
|
+
app.use((req, res) => {
|
|
115
|
+
res.status(404);
|
|
116
|
+
if (isApiShapedPath(req.path)) {
|
|
117
|
+
return res.json(apiNotFoundBody(req.path));
|
|
118
|
+
}
|
|
119
|
+
return res.type('text/plain').send('404 — not found');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
return app;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Start only when run as the entry (`node src/platform-server.js`). Importing the
|
|
126
|
+
// module (the smoke test) must NOT bind a port.
|
|
127
|
+
if (require.main === module) {
|
|
128
|
+
const app = buildPlatformApp();
|
|
129
|
+
const httpServer = http.createServer(app);
|
|
130
|
+
httpServer.listen(PORT, HOST, () => {
|
|
131
|
+
console.log(`Cloud Bongos platform (GDS-only, no game; ADR 0062 R51) listening on ${HOST}:${PORT}`);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = { buildPlatformApp };
|