@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,268 @@
|
|
|
1
|
+
// src/module-loader/loader.js — the module loader (BV1.R41 / task 1410, ADR 0083).
|
|
2
|
+
//
|
|
3
|
+
// Replaces the CLOSED KNOWN_MODULES registry (src/modules.js) with DISCOVERY:
|
|
4
|
+
// it scans modules/*/module.json, validates each manifest (manifest-schema),
|
|
5
|
+
// checks its coreVersion against the doorway's CORE_VERSION, and exposes the
|
|
6
|
+
// discovered set so src/modules.js's resolver spans built-in + discovered, and
|
|
7
|
+
// routes.js mounts discovered module routers behind the kernel's auth/audit.
|
|
8
|
+
//
|
|
9
|
+
// SAFE-BY-CONSTRUCTION during the strangler migration: with no modules/ dir
|
|
10
|
+
// (the state until BV1.R43 moves dev-box), discovery returns EMPTY and every
|
|
11
|
+
// function below is a no-op — OTB behaves byte-identically. As built-ins move
|
|
12
|
+
// out, they become discovered manifests and the closed registry shrinks.
|
|
13
|
+
//
|
|
14
|
+
// require-time is intentionally light (manifest-schema + semver only). The
|
|
15
|
+
// doorway CORE_VERSION is read LAZILY inside coreVersion() so requiring this from
|
|
16
|
+
// src/modules.js can never form an eval-time cycle through module-api → auth.
|
|
17
|
+
|
|
18
|
+
const fs = require('node:fs');
|
|
19
|
+
const path = require('node:path');
|
|
20
|
+
const { validateManifest } = require('./manifest-schema');
|
|
21
|
+
const { satisfies } = require('./semver');
|
|
22
|
+
const { resolveCoreRoot } = require('../instance-config');
|
|
23
|
+
|
|
24
|
+
// ADR 0108 §1: modules/ ships WITH the core package. resolveCoreRoot() returns
|
|
25
|
+
// the repo root today, so this is byte-identical for the live instance.
|
|
26
|
+
const DEFAULT_ROOTS = [path.join(resolveCoreRoot(), 'modules')];
|
|
27
|
+
|
|
28
|
+
// Lazy — avoids an eval-time require cycle (modules.js → loader → module-api →
|
|
29
|
+
// auth → …). By call time the graph is loaded; falls back to the known initial
|
|
30
|
+
// version if module-api is somehow unavailable (tooling contexts).
|
|
31
|
+
function coreVersion() {
|
|
32
|
+
try { return require('../module-api').CORE_VERSION; } catch { return '1.0.0'; }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Discover + validate + coreVersion-check every modules/*/module.json. Pure-ish
|
|
36
|
+
// (reads disk; no mutation of app state). Returns:
|
|
37
|
+
// { loaded: [{key,dir,manifest}], skipped: [{key,dir,reason}], errors: [{dir,errors}] }
|
|
38
|
+
function discoverModules({ roots = DEFAULT_ROOTS, core = coreVersion() } = {}) {
|
|
39
|
+
const loaded = [];
|
|
40
|
+
const skipped = [];
|
|
41
|
+
const errors = [];
|
|
42
|
+
const seen = new Set();
|
|
43
|
+
|
|
44
|
+
for (const root of roots) {
|
|
45
|
+
let entries;
|
|
46
|
+
try { entries = fs.readdirSync(root, { withFileTypes: true }); }
|
|
47
|
+
catch (e) { if (e.code === 'ENOENT') continue; throw e; }
|
|
48
|
+
|
|
49
|
+
for (const ent of entries) {
|
|
50
|
+
if (!ent.isDirectory()) continue;
|
|
51
|
+
const dir = path.join(root, ent.name);
|
|
52
|
+
const manifestPath = path.join(dir, 'module.json');
|
|
53
|
+
let raw;
|
|
54
|
+
try { raw = fs.readFileSync(manifestPath, 'utf8'); }
|
|
55
|
+
catch (e) { if (e.code === 'ENOENT') continue; errors.push({ dir, errors: [`unreadable module.json: ${e.message}`] }); continue; }
|
|
56
|
+
|
|
57
|
+
let parsed;
|
|
58
|
+
try { parsed = JSON.parse(raw); }
|
|
59
|
+
catch (e) { errors.push({ dir, errors: [`module.json is not valid JSON: ${e.message}`] }); continue; }
|
|
60
|
+
|
|
61
|
+
const { valid, errors: errs } = validateManifest(parsed);
|
|
62
|
+
if (!valid) { errors.push({ dir, errors: errs }); continue; }
|
|
63
|
+
if (parsed.key !== ent.name) { errors.push({ dir, errors: [`manifest key "${parsed.key}" must match directory name "${ent.name}"`] }); continue; }
|
|
64
|
+
if (seen.has(parsed.key)) { errors.push({ dir, errors: [`duplicate module key "${parsed.key}"`] }); continue; }
|
|
65
|
+
seen.add(parsed.key);
|
|
66
|
+
|
|
67
|
+
if (!satisfies(core, parsed.coreVersion)) {
|
|
68
|
+
skipped.push({ key: parsed.key, dir, reason: `coreVersion "${parsed.coreVersion}" not satisfied by core ${core}` });
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
loaded.push({ key: parsed.key, dir, manifest: parsed });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return { loaded, skipped, errors };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Cached singleton for app code (lazy, like src/modules.js's modules()).
|
|
78
|
+
let _cache = null;
|
|
79
|
+
function discovered(opts) { return (_cache ||= discoverModules(opts)); }
|
|
80
|
+
function _reset() { _cache = null; _startedPollers = []; }
|
|
81
|
+
|
|
82
|
+
// The discovered manifests as MODULE_REGISTRY-shaped entries, so src/modules.js
|
|
83
|
+
// can merge them with its built-in registry. Empty until a module exists.
|
|
84
|
+
function discoveredRegistry(opts) {
|
|
85
|
+
const out = {};
|
|
86
|
+
for (const { key, manifest, dir } of discovered(opts).loaded) {
|
|
87
|
+
out[key] = {
|
|
88
|
+
title: manifest.title,
|
|
89
|
+
description: manifest.description,
|
|
90
|
+
default: manifest.default === true,
|
|
91
|
+
contributes: manifest.contributes || {},
|
|
92
|
+
_discovered: true,
|
|
93
|
+
_dir: dir,
|
|
94
|
+
_provides: manifest.provides || [],
|
|
95
|
+
_consumes: manifest.consumes || [],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Mount each discovered + ENABLED module's route factories onto `router`. A
|
|
102
|
+
// module declares contributes.routes:["box"] → factory at modules/<key>/routes/box.js
|
|
103
|
+
// exporting a function returning an express Router. Auth model: audit is composed
|
|
104
|
+
// at the kernel level in routes.js before this is called; each route self-gates at
|
|
105
|
+
// its required rank via api.requireBuilder / api.requireRank (public read routes
|
|
106
|
+
// need no gate). The BV1.R44 fitness check enforces that every write route is
|
|
107
|
+
// rank-gated. Returns the count mounted. No-op when nothing is discovered/enabled.
|
|
108
|
+
function mountModuleRoutes(router, { isEnabled } = {}, opts) {
|
|
109
|
+
let mounted = 0;
|
|
110
|
+
for (const { key, dir, manifest } of discovered(opts).loaded) {
|
|
111
|
+
if (typeof isEnabled === 'function' && !isEnabled(key)) continue;
|
|
112
|
+
const routeKeys = (manifest.contributes && manifest.contributes.routes) || [];
|
|
113
|
+
for (const rk of routeKeys) {
|
|
114
|
+
const factory = require(path.join(dir, 'routes', `${rk}.js`));
|
|
115
|
+
const sub = typeof factory === 'function' ? factory() : factory;
|
|
116
|
+
router.use(sub);
|
|
117
|
+
mounted += 1;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return mounted;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Hall-widget client scripts contributed by enabled modules (BV1.R75, ADR 0062 §4).
|
|
124
|
+
// A module that owns a builders'-hall UI section declares contributes.uiSections in
|
|
125
|
+
// its manifest AND ships a browser script at modules/<key>/public/hall-widget.js that
|
|
126
|
+
// calls window.OTB.contributeHallWidget({...}). This returns, for each discovered +
|
|
127
|
+
// ENABLED module that declares uiSections and actually ships that file, the SERVED URL
|
|
128
|
+
// the hall HTML should <script>-load — i.e. /modules/<key>/public/hall-widget.js (the
|
|
129
|
+
// static mount serve-internal.js adds under /modules/). The hall twin of
|
|
130
|
+
// mountModuleRoutes: an enabled module's widget appears, a disabled one vanishes (it's
|
|
131
|
+
// never injected), and contributeHallWidget itself no-ops a stale widget whose module
|
|
132
|
+
// is off. No-op (empty list) until a module ships a hall widget — same SAFE-BY-
|
|
133
|
+
// CONSTRUCTION posture as every other seam here. Returns [{ key, src }].
|
|
134
|
+
function hallWidgetScripts({ isEnabled } = {}, opts) {
|
|
135
|
+
const out = [];
|
|
136
|
+
for (const { key, dir, manifest } of discovered(opts).loaded) {
|
|
137
|
+
if (typeof isEnabled === 'function' && !isEnabled(key)) continue;
|
|
138
|
+
const sections = (manifest.contributes && manifest.contributes.uiSections) || [];
|
|
139
|
+
if (sections.length === 0) continue;
|
|
140
|
+
const scriptPath = path.join(dir, 'public', 'hall-widget.js');
|
|
141
|
+
if (!fs.existsSync(scriptPath)) continue; // declarative-only uiSections (e.g. status-page section)
|
|
142
|
+
out.push({ key, src: `/modules/${key}/public/hall-widget.js` });
|
|
143
|
+
}
|
|
144
|
+
return out;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Host-routed static web surfaces contributed by enabled modules (BV1.R84, ADR 0093
|
|
148
|
+
// §1 / 02-module-map §6 — a web surface is first-class). A module that owns a web
|
|
149
|
+
// surface (e.g. the status dashboard at status.<apex>) declares
|
|
150
|
+
// contributes.webSurfaces:[{ host:"status.", dir:"public" }] in its manifest AND
|
|
151
|
+
// ships that static dir at modules/<key>/<dir>/. This returns, for each discovered +
|
|
152
|
+
// ENABLED module that declares webSurfaces and actually ships the directory, the
|
|
153
|
+
// SERVING descriptor serve-internal.js iterates to route by Host header:
|
|
154
|
+
// { key, host, dir } — host is the lowercase Host-header prefix; dir is the
|
|
155
|
+
// ABSOLUTE on-disk path of the static directory.
|
|
156
|
+
// The Host-routed twin of mountModuleRoutes / hallWidgetScripts: an enabled module's
|
|
157
|
+
// surface answers on its host, a disabled one vanishes (it's never returned, so
|
|
158
|
+
// serve-internal never routes its host). No-op (empty list) until a module ships a
|
|
159
|
+
// web surface — same SAFE-BY-CONSTRUCTION posture as every other seam here. Pure
|
|
160
|
+
// (reads disk only). Exported + module-agnostic so serve-internal hardcodes no key.
|
|
161
|
+
function moduleWebSurfaces({ isEnabled } = {}, opts) {
|
|
162
|
+
const out = [];
|
|
163
|
+
for (const { key, dir, manifest } of discovered(opts).loaded) {
|
|
164
|
+
if (typeof isEnabled === 'function' && !isEnabled(key)) continue;
|
|
165
|
+
const surfaces = (manifest.contributes && manifest.contributes.webSurfaces) || [];
|
|
166
|
+
for (const s of surfaces) {
|
|
167
|
+
if (!s || typeof s.host !== 'string' || typeof s.dir !== 'string') continue;
|
|
168
|
+
const abs = path.join(dir, s.dir);
|
|
169
|
+
let isDir = false;
|
|
170
|
+
try { isDir = fs.statSync(abs).isDirectory(); } catch { isDir = false; }
|
|
171
|
+
if (!isDir) continue; // declared but not shipped → skip (no host routed)
|
|
172
|
+
out.push({ key, host: s.host.toLowerCase(), dir: abs });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Started poller handles (key, name, module), so stopModulePollers stops exactly
|
|
179
|
+
// what startModulePollers started — and a test can introspect them.
|
|
180
|
+
let _startedPollers = [];
|
|
181
|
+
|
|
182
|
+
// Start each discovered + ENABLED module's background pollers. A module declares
|
|
183
|
+
// contributes.pollers:["discord-bot"] → a start/stop module at
|
|
184
|
+
// modules/<key>/pollers/discord-bot.js. NON-BLOCKING + failure-isolated: start()
|
|
185
|
+
// may return a promise (e.g. the Discord gateway connect); we fire it and attach
|
|
186
|
+
// a .catch so a poller problem can never take the boot — the API/game stay up.
|
|
187
|
+
// This is the module-agnostic successor to the hardcoded `discordBot.start()`
|
|
188
|
+
// block server.js used to carry (BV1.R47 / task 1416). `deps` is forwarded to
|
|
189
|
+
// each poller's start(); `{ isEnabled }` gates by the instance's module config.
|
|
190
|
+
// No-op when nothing is discovered/enabled. Returns the started-handle list.
|
|
191
|
+
function startModulePollers(deps = {}, { isEnabled } = {}, opts) {
|
|
192
|
+
const started = [];
|
|
193
|
+
for (const { key, dir, manifest } of discovered(opts).loaded) {
|
|
194
|
+
if (typeof isEnabled === 'function' && !isEnabled(key)) continue;
|
|
195
|
+
const pollerKeys = (manifest.contributes && manifest.contributes.pollers) || [];
|
|
196
|
+
for (const pk of pollerKeys) {
|
|
197
|
+
const pollerPath = path.join(dir, 'pollers', `${pk}.js`);
|
|
198
|
+
let poller;
|
|
199
|
+
try {
|
|
200
|
+
poller = require(pollerPath);
|
|
201
|
+
} catch (e) {
|
|
202
|
+
// No modules/<key>/pollers/<pk>.js → a DECLARATIVE-ONLY / non-web poller
|
|
203
|
+
// (e.g. dev-box's box-lifecycle sweep runs on the control plane, not in
|
|
204
|
+
// this process). Skip silently — only a web-process poller ships a file
|
|
205
|
+
// here. A file that EXISTS but throws is a real error (the catch below).
|
|
206
|
+
if (e && e.code === 'MODULE_NOT_FOUND' && String(e.message).includes(pollerPath)) continue;
|
|
207
|
+
console.error(`[module-loader] poller ${key}/${pk} failed to load: ${e && e.message ? e.message : e}`);
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
try {
|
|
211
|
+
if (poller && typeof poller.start === 'function') {
|
|
212
|
+
const r = poller.start(deps);
|
|
213
|
+
if (r && typeof r.then === 'function') {
|
|
214
|
+
r.catch((e) => console.error(`[module-loader] poller ${key}/${pk} start error: ${e && e.message ? e.message : e}`));
|
|
215
|
+
}
|
|
216
|
+
started.push({ key, poller: pk, handle: poller });
|
|
217
|
+
}
|
|
218
|
+
} catch (e) {
|
|
219
|
+
console.error(`[module-loader] poller ${key}/${pk} start threw: ${e && e.message ? e.message : e}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
_startedPollers = started;
|
|
224
|
+
return started;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Stop every poller startModulePollers started, in reverse order. Awaits each
|
|
228
|
+
// stop() (the Discord gateway close is async) so a caller can sequence a clean
|
|
229
|
+
// shutdown: `loader.stopModulePollers().finally(() => process.exit(0))`. Errors
|
|
230
|
+
// are isolated — one poller's failed stop never blocks the others. Returns the
|
|
231
|
+
// count stopped.
|
|
232
|
+
async function stopModulePollers() {
|
|
233
|
+
const handles = _startedPollers.slice().reverse();
|
|
234
|
+
_startedPollers = [];
|
|
235
|
+
for (const { key, poller, handle } of handles) {
|
|
236
|
+
try {
|
|
237
|
+
if (handle && typeof handle.stop === 'function') await handle.stop();
|
|
238
|
+
} catch (e) {
|
|
239
|
+
console.error(`[module-loader] poller ${key}/${poller} failed to stop: ${e && e.message ? e.message : e}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return handles.length;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// A snapshot for observability / a /watch tile.
|
|
246
|
+
function loaderSnapshot(opts) {
|
|
247
|
+
const d = discovered(opts);
|
|
248
|
+
return {
|
|
249
|
+
loaded: d.loaded.map((m) => m.key),
|
|
250
|
+
skipped: d.skipped,
|
|
251
|
+
errors: d.errors,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
module.exports = {
|
|
256
|
+
discoverModules,
|
|
257
|
+
discovered,
|
|
258
|
+
discoveredRegistry,
|
|
259
|
+
mountModuleRoutes,
|
|
260
|
+
hallWidgetScripts,
|
|
261
|
+
moduleWebSurfaces,
|
|
262
|
+
startModulePollers,
|
|
263
|
+
stopModulePollers,
|
|
264
|
+
loaderSnapshot,
|
|
265
|
+
coreVersion,
|
|
266
|
+
DEFAULT_ROOTS,
|
|
267
|
+
_reset,
|
|
268
|
+
};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// src/module-loader/manifest-schema.js — the module.json manifest schema +
|
|
2
|
+
// validator (BV1.R38 / task 1407, ADR 0083 / design 04§4).
|
|
3
|
+
//
|
|
4
|
+
// A module.json is the single declared contract for what a module contributes.
|
|
5
|
+
// It is the per-module externalization of the closed MODULE_REGISTRY entries in
|
|
6
|
+
// src/modules.js (which the loader, BV1.R41, replaces with manifest discovery).
|
|
7
|
+
// The loader and the fitness gate both act on it, so "maintaining a module"
|
|
8
|
+
// largely means "keeping its manifest true."
|
|
9
|
+
//
|
|
10
|
+
// THE SCHEMA (module.json):
|
|
11
|
+
// {
|
|
12
|
+
// "key": "dev-box", // REQUIRED. ^[a-z][a-z0-9-]*$ ; must match the module's dir name.
|
|
13
|
+
// "title": "Dev boxes", // REQUIRED. Human label.
|
|
14
|
+
// "description": "…", // REQUIRED. One sentence.
|
|
15
|
+
// "coreVersion": "^1.0.0", // REQUIRED. semver range of src/module-api.js CORE_VERSION it supports.
|
|
16
|
+
// "default": false, // OPTIONAL (default false). Enablement fail-safe when no config names it.
|
|
17
|
+
// "author": "…", // OPTIONAL. Attribution (ADR 0107 §2) — portable, not a cross-GDS FK.
|
|
18
|
+
// "origin": "…", // OPTIONAL. Origin instance/project this module was built in.
|
|
19
|
+
// "license": "…", // OPTIONAL. e.g. "AGPL-3.0" — the license this module is offered under.
|
|
20
|
+
// "maintainer": "…", // OPTIONAL. Who to credit/contact if this module is upstreamed.
|
|
21
|
+
// "contributes": { // REQUIRED object (may be empty). What the module mounts:
|
|
22
|
+
// "routes": ["box"], // route-factory keys (mounted behind kernel-composed auth)
|
|
23
|
+
// "rooms": ["WorldRoom"], // Colyseus room classes (realtime seam)
|
|
24
|
+
// "pollers": ["box-lifecycle"],// background pollers to start/stop
|
|
25
|
+
// "disciplines": ["artist"], // disciplines this module adds
|
|
26
|
+
// "skills": ["otb-…"], // slash-command skills it ships
|
|
27
|
+
// "uiSections": ["boxes"], // hall/status UI sections it owns
|
|
28
|
+
// "webSurfaces": [{ "host": "status.", "dir": "public" }], // host-routed static web surfaces (BV1.R84)
|
|
29
|
+
// "migrations": true // true => modules/<key>/migrations/ exists (or an array of names)
|
|
30
|
+
// },
|
|
31
|
+
// "provides": ["reward"], // OPTIONAL. seam PORTS this module registers a provider for.
|
|
32
|
+
// "consumes": ["grade"], // OPTIONAL. seam ports this module resolves (required capabilities).
|
|
33
|
+
// "prerequisites": { "modules": ["economy"] } // OPTIONAL. other modules that must be enabled.
|
|
34
|
+
// }
|
|
35
|
+
//
|
|
36
|
+
// validateManifest(obj) -> { valid, errors[], manifest } — pure, no I/O.
|
|
37
|
+
// assertValidManifest(obj) throws on the first failure (loader convenience).
|
|
38
|
+
|
|
39
|
+
const { isValidRange } = require('./semver');
|
|
40
|
+
|
|
41
|
+
const KEY_RE = /^[a-z][a-z0-9-]*$/;
|
|
42
|
+
|
|
43
|
+
// contributes sub-keys that must be arrays of non-empty strings when present.
|
|
44
|
+
const ARRAY_OF_STRING_KEYS = ['routes', 'rooms', 'pollers', 'disciplines', 'skills', 'uiSections'];
|
|
45
|
+
// Every key contributes is ALLOWED to declare (anything else is a typo → error).
|
|
46
|
+
// webSurfaces (BV1.R84) is the host-routed static-surface seam — an array of
|
|
47
|
+
// objects, not strings, so it is validated separately below.
|
|
48
|
+
const ALLOWED_CONTRIBUTES = [...ARRAY_OF_STRING_KEYS, 'webSurfaces', 'migrations'];
|
|
49
|
+
|
|
50
|
+
// Top-level attribution fields (ADR 0107 §2) — optional, portable strings.
|
|
51
|
+
const ATTRIBUTION_KEYS = ['author', 'origin', 'license', 'maintainer'];
|
|
52
|
+
|
|
53
|
+
const isObj = (v) => v && typeof v === 'object' && !Array.isArray(v);
|
|
54
|
+
const isStr = (v) => typeof v === 'string' && v.length > 0;
|
|
55
|
+
const isStrArray = (v) => Array.isArray(v) && v.every(isStr);
|
|
56
|
+
|
|
57
|
+
// A webSurface entry: { host: "<subdomain-prefix>.", dir: "<static-dir-rel-to-module>" }.
|
|
58
|
+
// `host` is the lowercase Host-header prefix the surface answers on (e.g. "status."
|
|
59
|
+
// → status.<apex>); `dir` is the module-relative directory of static files to serve
|
|
60
|
+
// (e.g. "public"). Both required, non-empty strings; `dir` must stay inside the
|
|
61
|
+
// module (no absolute / "..").
|
|
62
|
+
const isWebSurface = (v) =>
|
|
63
|
+
isObj(v) && isStr(v.host) && isStr(v.dir) && !v.dir.startsWith('/') && !v.dir.split(/[\\/]/).includes('..');
|
|
64
|
+
const isWebSurfaceArray = (v) => Array.isArray(v) && v.every(isWebSurface);
|
|
65
|
+
|
|
66
|
+
function validateManifest(obj) {
|
|
67
|
+
const errors = [];
|
|
68
|
+
const E = (msg) => errors.push(msg);
|
|
69
|
+
|
|
70
|
+
if (!isObj(obj)) {
|
|
71
|
+
return { valid: false, errors: ['manifest must be a JSON object'], manifest: null };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// --- required scalar fields ---
|
|
75
|
+
if (!isStr(obj.key)) E('key: required non-empty string');
|
|
76
|
+
else if (!KEY_RE.test(obj.key)) E(`key: "${obj.key}" must match ${KEY_RE} (lowercase, kebab-case)`);
|
|
77
|
+
|
|
78
|
+
if (!isStr(obj.title)) E('title: required non-empty string');
|
|
79
|
+
if (!isStr(obj.description)) E('description: required non-empty string');
|
|
80
|
+
|
|
81
|
+
if (!isStr(obj.coreVersion)) E('coreVersion: required non-empty semver range string (e.g. "^1.0.0")');
|
|
82
|
+
else if (!isValidRange(obj.coreVersion)) E(`coreVersion: "${obj.coreVersion}" is not a valid semver range`);
|
|
83
|
+
|
|
84
|
+
// --- optional default ---
|
|
85
|
+
if ('default' in obj && typeof obj.default !== 'boolean') E('default: must be a boolean when present');
|
|
86
|
+
|
|
87
|
+
// --- optional attribution (ADR 0107 §2 — portable credit, not a cross-GDS FK) ---
|
|
88
|
+
for (const k of ATTRIBUTION_KEYS) {
|
|
89
|
+
if (k in obj && !isStr(obj[k])) E(`${k}: must be a non-empty string when present`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// --- contributes (required object) ---
|
|
93
|
+
if (!isObj(obj.contributes)) {
|
|
94
|
+
E('contributes: required object (use {} if the module contributes nothing)');
|
|
95
|
+
} else {
|
|
96
|
+
for (const k of Object.keys(obj.contributes)) {
|
|
97
|
+
if (!ALLOWED_CONTRIBUTES.includes(k)) {
|
|
98
|
+
E(`contributes.${k}: unknown key (allowed: ${ALLOWED_CONTRIBUTES.join(', ')})`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
for (const k of ARRAY_OF_STRING_KEYS) {
|
|
102
|
+
if (k in obj.contributes && !isStrArray(obj.contributes[k])) {
|
|
103
|
+
E(`contributes.${k}: must be an array of non-empty strings`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if ('webSurfaces' in obj.contributes && !isWebSurfaceArray(obj.contributes.webSurfaces)) {
|
|
107
|
+
E('contributes.webSurfaces: must be an array of { host: "<prefix>.", dir: "<module-relative dir>" } objects (dir inside the module, no absolute path or "..")');
|
|
108
|
+
}
|
|
109
|
+
if ('migrations' in obj.contributes) {
|
|
110
|
+
const m = obj.contributes.migrations;
|
|
111
|
+
if (typeof m !== 'boolean' && !isStrArray(m)) {
|
|
112
|
+
E('contributes.migrations: must be true/false or an array of migration names');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// --- optional seam declarations ---
|
|
118
|
+
if ('provides' in obj && !isStrArray(obj.provides)) E('provides: must be an array of non-empty strings (port names)');
|
|
119
|
+
if ('consumes' in obj && !isStrArray(obj.consumes)) E('consumes: must be an array of non-empty strings (port names)');
|
|
120
|
+
|
|
121
|
+
// --- optional prerequisites ---
|
|
122
|
+
if ('prerequisites' in obj) {
|
|
123
|
+
if (!isObj(obj.prerequisites)) E('prerequisites: must be an object');
|
|
124
|
+
else if ('modules' in obj.prerequisites && !isStrArray(obj.prerequisites.modules)) {
|
|
125
|
+
E('prerequisites.modules: must be an array of module-key strings');
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return { valid: errors.length === 0, errors, manifest: errors.length === 0 ? obj : null };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function assertValidManifest(obj, label = 'module.json') {
|
|
133
|
+
const { valid, errors } = validateManifest(obj);
|
|
134
|
+
if (!valid) {
|
|
135
|
+
throw new Error(`${label} invalid:\n - ${errors.join('\n - ')}`);
|
|
136
|
+
}
|
|
137
|
+
return obj;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
module.exports = { validateManifest, assertValidManifest, KEY_RE, ALLOWED_CONTRIBUTES, ARRAY_OF_STRING_KEYS, ATTRIBUTION_KEYS };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// src/module-loader/provenance.js — pure "who built this module" classifier
|
|
2
|
+
// (ADR 0107 §9). A module is OWN-BUILT if its manifest names no `origin`, or
|
|
3
|
+
// names this instance itself; it is CORE-LOADED if `origin` names a
|
|
4
|
+
// different project — i.e. it flowed in from the shared Cloud Bongos catalog
|
|
5
|
+
// (ADR 0107 §1's upstream/downstream arrows meet here).
|
|
6
|
+
//
|
|
7
|
+
// No module in this tree names a FOREIGN origin today — every module here was
|
|
8
|
+
// built in this repo. Some name THIS instance as their origin (e.g. the
|
|
9
|
+
// provisioning module's "Off the Boats (the first Cloud Bongos instance…)"),
|
|
10
|
+
// which is still own-built. The split (core-loaded) side lights up only once a
|
|
11
|
+
// module is actually pulled back in from the shared catalog under a different
|
|
12
|
+
// project's name (ADR 0107 §8 pipeline, tasks 1770/1772).
|
|
13
|
+
|
|
14
|
+
function deriveProvenance(origin, ownProjectName) {
|
|
15
|
+
const o = origin && String(origin).trim();
|
|
16
|
+
if (!o) return 'own';
|
|
17
|
+
const own = ownProjectName && String(ownProjectName).trim().toLowerCase();
|
|
18
|
+
// "names this instance itself" (ADR 0107 §9) — an origin that IS, or leads
|
|
19
|
+
// with, the own project name is own-built (a self-referential origin like
|
|
20
|
+
// "Off the Boats (the first Cloud Bongos instance)" counts). Only an origin
|
|
21
|
+
// naming a DIFFERENT project is core-loaded from the shared catalog. (An
|
|
22
|
+
// exact `===` was too brittle: it was written when no module set `origin`,
|
|
23
|
+
// so it never met a real, descriptive value — task 1776 re-land.)
|
|
24
|
+
if (!own || o.toLowerCase().startsWith(own)) return 'own';
|
|
25
|
+
return 'core';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = { deriveProvenance };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// src/module-loader/semver.js — a tiny, dependency-free semver checker for the
|
|
2
|
+
// module system (BV1.R38 / task 1407, ADR 0083).
|
|
3
|
+
//
|
|
4
|
+
// We deliberately do NOT pull in the `semver` npm package: the project is a
|
|
5
|
+
// no-bundler, dependency-minimal monolith, and the module-system only needs a
|
|
6
|
+
// small, well-understood subset — exact, caret (^), tilde (~), comparator
|
|
7
|
+
// ranges (>=, >, <=, <, =), and "*"/"" (any). A module declares the
|
|
8
|
+
// `coreVersion` range it supports; the loader (BV1.R41) checks it against
|
|
9
|
+
// CORE_VERSION from src/module-api.js; `bongos upgrade` (BV1.R50) reuses this.
|
|
10
|
+
|
|
11
|
+
const SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)$/;
|
|
12
|
+
|
|
13
|
+
// Parse "1.2.3" -> [1,2,3], or null if not a clean release version (we don't
|
|
14
|
+
// support pre-release/build metadata — the core version is always plain X.Y.Z).
|
|
15
|
+
function parseVersion(v) {
|
|
16
|
+
if (typeof v !== 'string') return null;
|
|
17
|
+
const m = SEMVER_RE.exec(v.trim());
|
|
18
|
+
return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function cmp(a, b) {
|
|
22
|
+
for (let i = 0; i < 3; i += 1) {
|
|
23
|
+
if (a[i] !== b[i]) return a[i] < b[i] ? -1 : 1;
|
|
24
|
+
}
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// A single comparator (one space-separated token) against a parsed version.
|
|
29
|
+
function satisfiesComparator(version, token) {
|
|
30
|
+
const t = token.trim();
|
|
31
|
+
if (t === '' || t === '*' || t === 'x' || t === 'X') return true;
|
|
32
|
+
|
|
33
|
+
// caret: ^1.2.3 -> >=1.2.3 <2.0.0 ; ^0.2.3 -> >=0.2.3 <0.3.0 ; ^0.0.3 -> >=0.0.3 <0.0.4
|
|
34
|
+
if (t.startsWith('^')) {
|
|
35
|
+
const base = parseVersion(t.slice(1));
|
|
36
|
+
if (!base) return false;
|
|
37
|
+
if (cmp(version, base) < 0) return false;
|
|
38
|
+
let upper;
|
|
39
|
+
if (base[0] > 0) upper = [base[0] + 1, 0, 0];
|
|
40
|
+
else if (base[1] > 0) upper = [0, base[1] + 1, 0];
|
|
41
|
+
else upper = [0, 0, base[2] + 1];
|
|
42
|
+
return cmp(version, upper) < 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// tilde: ~1.2.3 -> >=1.2.3 <1.3.0
|
|
46
|
+
if (t.startsWith('~')) {
|
|
47
|
+
const base = parseVersion(t.slice(1));
|
|
48
|
+
if (!base) return false;
|
|
49
|
+
if (cmp(version, base) < 0) return false;
|
|
50
|
+
return cmp(version, [base[0], base[1] + 1, 0]) < 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// comparator ranges
|
|
54
|
+
const m = /^(>=|<=|>|<|=)?\s*(\d+\.\d+\.\d+)$/.exec(t);
|
|
55
|
+
if (!m) return false;
|
|
56
|
+
const op = m[1] || '=';
|
|
57
|
+
const base = parseVersion(m[2]);
|
|
58
|
+
if (!base) return false;
|
|
59
|
+
const c = cmp(version, base);
|
|
60
|
+
switch (op) {
|
|
61
|
+
case '>=': return c >= 0;
|
|
62
|
+
case '<=': return c <= 0;
|
|
63
|
+
case '>': return c > 0;
|
|
64
|
+
case '<': return c < 0;
|
|
65
|
+
case '=': return c === 0;
|
|
66
|
+
default: return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Does `version` (an exact X.Y.Z) satisfy `range`? A range is space-separated
|
|
71
|
+
// comparators ALL of which must hold (AND); "||" separates alternative ranges
|
|
72
|
+
// (OR). Returns false on an unparseable version.
|
|
73
|
+
function satisfies(version, range) {
|
|
74
|
+
const v = parseVersion(version);
|
|
75
|
+
if (!v) return false;
|
|
76
|
+
if (range == null || range === '') return true;
|
|
77
|
+
const alternatives = String(range).split('||');
|
|
78
|
+
return alternatives.some((alt) =>
|
|
79
|
+
alt.trim().split(/\s+/).filter(Boolean).every((tok) => satisfiesComparator(v, tok)));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Is `range` a syntactically valid range string we can evaluate? Used by the
|
|
83
|
+
// manifest validator so a typo'd coreVersion is caught at validate-time, not at
|
|
84
|
+
// mount-time.
|
|
85
|
+
function isValidRange(range) {
|
|
86
|
+
if (range == null) return false;
|
|
87
|
+
const s = String(range).trim();
|
|
88
|
+
if (s === '' || s === '*') return true;
|
|
89
|
+
return s.split('||').every((alt) => {
|
|
90
|
+
const tokens = alt.trim().split(/\s+/).filter(Boolean);
|
|
91
|
+
if (tokens.length === 0) return false;
|
|
92
|
+
return tokens.every((t) => {
|
|
93
|
+
if (t === '*' || t === 'x' || t === 'X') return true;
|
|
94
|
+
if (t.startsWith('^') || t.startsWith('~')) return parseVersion(t.slice(1)) != null;
|
|
95
|
+
return /^(>=|<=|>|<|=)?\s*\d+\.\d+\.\d+$/.test(t);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
module.exports = { parseVersion, satisfies, isValidRange, cmp };
|