@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,147 @@
|
|
|
1
|
+
// tests/module_route_rank.mjs — BV1.R44 / task 1413 (ADR 0083): the route-rank
|
|
2
|
+
// invariant (src/bongos/route-rank-check.js) now ALSO covers module routes
|
|
3
|
+
// (modules/<key>/routes/*.js), and recognizes the module doorway gate prefix
|
|
4
|
+
// (api.requireRank, not just core's auth.requireRank). Hermetic: module routes
|
|
5
|
+
// are written into a temp dir passed as modulesDir; the live (clean) core routes
|
|
6
|
+
// are reused so the only findings come from the fixture. DB-free → the `unit` gate.
|
|
7
|
+
import assert from 'node:assert/strict';
|
|
8
|
+
import { test } from 'node:test';
|
|
9
|
+
import { createRequire } from 'node:module';
|
|
10
|
+
import fs from 'node:fs';
|
|
11
|
+
import os from 'node:os';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import { fileURLToPath } from 'node:url';
|
|
14
|
+
|
|
15
|
+
const require = createRequire(import.meta.url);
|
|
16
|
+
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
17
|
+
const rrc = require(path.join(ROOT, 'src', 'bongos', 'route-rank-check.js'));
|
|
18
|
+
|
|
19
|
+
// Write modules/<key>/routes/<file> under a fresh temp modules root; return the root.
|
|
20
|
+
function modulesWith(key, file, body) {
|
|
21
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'rrc-mods-'));
|
|
22
|
+
const rdir = path.join(root, key, 'routes');
|
|
23
|
+
fs.mkdirSync(rdir, { recursive: true });
|
|
24
|
+
fs.writeFileSync(path.join(rdir, file), body);
|
|
25
|
+
return root;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const ungatedRoute = [
|
|
29
|
+
'module.exports = () => {',
|
|
30
|
+
" router.post('/shop/charge', h);", // NO gate → unknown → blocker (write method)
|
|
31
|
+
' return router;',
|
|
32
|
+
'};',
|
|
33
|
+
].join('\n');
|
|
34
|
+
|
|
35
|
+
const gatedRoute = [
|
|
36
|
+
"const api = require('../../../src/module-api');",
|
|
37
|
+
'module.exports = () => {',
|
|
38
|
+
" router.post('/shop/charge', api.requireRank('metic', 'archon'), h);", // doorway gate
|
|
39
|
+
' return router;',
|
|
40
|
+
'};',
|
|
41
|
+
].join('\n');
|
|
42
|
+
|
|
43
|
+
// ---- the doorway (api.) prefix is recognized exactly like core's auth. ----
|
|
44
|
+
test('classifyRank: api.requireRank (module doorway) classifies like auth.requireRank', () => {
|
|
45
|
+
assert.equal(rrc.classifyText("router.post('/x', api.requireRank('archon'), h);")[0].rank, 'archon');
|
|
46
|
+
assert.equal(rrc.classifyText("router.post('/x', api.requireRank('metic', 'archon'), h);")[0].rank, 'metic+archon');
|
|
47
|
+
assert.equal(rrc.classifyText("router.get('/x', api.requireBuilder, h);")[0].rank, 'any-builder');
|
|
48
|
+
assert.equal(rrc.classifyText("router.post('/x', api.requireBfgPrincipal, h);")[0].rank, 'bfg-principal');
|
|
49
|
+
// core's auth. prefix still works (no regression)
|
|
50
|
+
assert.equal(rrc.classifyText("router.post('/x', auth.requireRank('archon'), h);")[0].rank, 'archon');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// ---- discovery spans core + module route files ----
|
|
54
|
+
test('discoverRouteFiles: finds modules/<key>/routes/*.js with a modules/ rel label, alongside core', () => {
|
|
55
|
+
const mods = modulesWith('shop', 'bag.js', ungatedRoute);
|
|
56
|
+
const found = rrc.discoverRouteFiles({ modulesDir: mods });
|
|
57
|
+
assert.ok(found.some((f) => f.rel === 'modules/shop/routes/bag.js'), 'the module route file must be discovered');
|
|
58
|
+
assert.ok(found.some((f) => f.rel.startsWith('src/bongos/routes/')), 'core route files are still discovered');
|
|
59
|
+
fs.rmSync(mods, { recursive: true, force: true });
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// ---- the done-when: an ungated module WRITE route reds the build ----
|
|
63
|
+
test('checkRouteRanks: an ungated module write route is a blocker (red build)', () => {
|
|
64
|
+
const mods = modulesWith('shop', 'bag.js', ungatedRoute);
|
|
65
|
+
const res = rrc.checkRouteRanks({ modulesDir: mods }); // live (clean) core routes + temp module
|
|
66
|
+
const f = res.findings.find((x) => x.route === 'POST /shop/charge');
|
|
67
|
+
assert.ok(f, 'an ungated module write route must surface a finding');
|
|
68
|
+
assert.equal(f.severity, 'blocker');
|
|
69
|
+
assert.equal(f.file, 'modules/shop/routes/bag.js');
|
|
70
|
+
assert.equal(res.hardFail, true);
|
|
71
|
+
fs.rmSync(mods, { recursive: true, force: true });
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// ---- the positive side: a doorway-gated module write route is NOT flagged ----
|
|
75
|
+
test('checkRouteRanks: a module write route gated via api.requireRank passes (no false positive)', () => {
|
|
76
|
+
const mods = modulesWith('shop', 'bag.js', gatedRoute);
|
|
77
|
+
const res = rrc.checkRouteRanks({ modulesDir: mods });
|
|
78
|
+
assert.ok(!res.findings.some((x) => x.route === 'POST /shop/charge'), 'a doorway-gated module write route must NOT be flagged');
|
|
79
|
+
assert.equal(res.hardFail, false, 'clean core + a properly gated module route = no hard fail');
|
|
80
|
+
fs.rmSync(mods, { recursive: true, force: true });
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// ---- byte-identical: with no modules/ dir, the result is the core-only set ----
|
|
84
|
+
test('checkRouteRanks: an absent modules/ dir leaves the core result clean (byte-identical pre-move tree)', () => {
|
|
85
|
+
const ghost = path.join(os.tmpdir(), 'rrc-no-such-modules-xyz-1413');
|
|
86
|
+
const res = rrc.checkRouteRanks({ modulesDir: ghost });
|
|
87
|
+
assert.ok(res.routeCount > 0, 'core routes still discovered');
|
|
88
|
+
assert.equal(res.findings.length, 0, 'no modules → only the (clean) core routes → zero findings');
|
|
89
|
+
assert.equal(res.hardFail, false);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// ---- the grade-time trigger fires on a module route change ----
|
|
93
|
+
test('ROUTE_FILE_RE matches a module route path (a module route change triggers the rank pre-pass)', () => {
|
|
94
|
+
assert.match('modules/dev-box/routes/box.js', rrc.ROUTE_FILE_RE);
|
|
95
|
+
assert.match('src/bongos/routes/tasks.js', rrc.ROUTE_FILE_RE); // core still matches
|
|
96
|
+
assert.ok(!rrc.ROUTE_FILE_RE.test('modules/dev-box/module.json'), 'a non-route module file does not trigger the pre-pass');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// ---- a rank DRIFT on a pinned MODULE route reds the build (BV1.R61) ----
|
|
100
|
+
// route_rank_check.mjs proves this for CORE pins (EXPECTED_RANKS). This proves it for
|
|
101
|
+
// MODULE pins (MODULE_EXPECTED_RANKS): the goal routes live in the lifecycle module,
|
|
102
|
+
// so their drift-protection only bites when that module is in scope. We synthesize a
|
|
103
|
+
// lifecycle module whose routes are ALL correctly gated EXCEPT the bounded-authoring
|
|
104
|
+
// keystone, silently hardened from 'any-builder' to archon — a drift the base
|
|
105
|
+
// "must classify" loop waves through (archon is a KNOWN rank), so ONLY the pin catches
|
|
106
|
+
// it. The executable form of "route-rank drift on a goal route is a red build".
|
|
107
|
+
test('checkRouteRanks: a rank drift on a pinned goal route (lifecycle module) is a blocker', () => {
|
|
108
|
+
const pins = rrc.MODULE_EXPECTED_RANKS.lifecycle;
|
|
109
|
+
assert.ok(pins && pins['POST /goals/:id/tasks'] === 'any-builder', 'the keystone must be pinned any-builder');
|
|
110
|
+
|
|
111
|
+
const emitLines = ["const api = require('../../../src/module-api');", 'module.exports = () => {'];
|
|
112
|
+
const emit = (key, rank) => {
|
|
113
|
+
const [method, route] = key.split(' ');
|
|
114
|
+
const m = method.toLowerCase();
|
|
115
|
+
if (key === 'POST /goals/:id/tasks') {
|
|
116
|
+
// DRIFT: pinned 'any-builder', silently hardened to archon (would lock
|
|
117
|
+
// sub-Metics out of the maneuverability grant — a regression the base invariant
|
|
118
|
+
// misses because archon is still a KNOWN rank).
|
|
119
|
+
emitLines.push(` router.${m}('${route}', api.requireRank('archon'), h);`);
|
|
120
|
+
} else if (rank === 'archon') {
|
|
121
|
+
emitLines.push(` router.${m}('${route}', api.requireRank('archon'), h);`);
|
|
122
|
+
} else if (rank === 'metic+archon') {
|
|
123
|
+
emitLines.push(` router.${m}('${route}', api.requireRank('metic', 'archon'), h);`);
|
|
124
|
+
} else { // any-builder
|
|
125
|
+
emitLines.push(` router.${m}('${route}', api.requireBuilder, h);`);
|
|
126
|
+
}
|
|
127
|
+
emitLines.push(' });', '', '', '', '', '', ''); // gap: keeps the 20-line lookahead off a neighbour's gate
|
|
128
|
+
};
|
|
129
|
+
// Emit every lifecycle pin at its EXPECTED rank, keystone LAST (downgraded) so
|
|
130
|
+
// nothing with requireRank('archon') sits inside its lookahead window.
|
|
131
|
+
for (const [key, rank] of Object.entries(pins)) if (key !== 'POST /goals/:id/tasks') emit(key, rank);
|
|
132
|
+
emit('POST /goals/:id/tasks', pins['POST /goals/:id/tasks']);
|
|
133
|
+
emitLines.push(' return router;', '};');
|
|
134
|
+
|
|
135
|
+
const mods = modulesWith('lifecycle', 'goals.js', emitLines.join('\n'));
|
|
136
|
+
const res = rrc.checkRouteRanks({ modulesDir: mods });
|
|
137
|
+
fs.rmSync(mods, { recursive: true, force: true });
|
|
138
|
+
|
|
139
|
+
const drift = res.findings.find((f) => f.route === 'POST /goals/:id/tasks');
|
|
140
|
+
assert.ok(drift, 'a drifted pinned goal route must surface a finding');
|
|
141
|
+
assert.equal(drift.rank, 'archon', 'the drifted route classifies as the WRONG (archon) rank');
|
|
142
|
+
assert.equal(drift.severity, 'blocker', 'a rank drift on the enforcement keystone is a hard fail');
|
|
143
|
+
assert.equal(res.hardFail, true, 'the build must go red');
|
|
144
|
+
// No missing-pin noise: every OTHER lifecycle pin was emitted at its expected rank,
|
|
145
|
+
// so the keystone drift is isolated (a '(missing)' finding would mean the emit is stale).
|
|
146
|
+
assert.ok(!res.findings.some((f) => f.rank === '(missing)'), 'all pins present; this is a drift, not a vanish');
|
|
147
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// tests/module_seams.mjs — seam registry hardening (BV1.R39 / task 1408, ADR 0083):
|
|
2
|
+
// boot-time port verification + async event fan-out. (The core register/resolve/
|
|
3
|
+
// emit/on round-trips are covered in tests/module_api.mjs, shipped with the doorway.)
|
|
4
|
+
import assert from 'node:assert/strict';
|
|
5
|
+
import { test } from 'node:test';
|
|
6
|
+
import { createRequire } from 'node:module';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
|
|
10
|
+
const require = createRequire(import.meta.url);
|
|
11
|
+
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
12
|
+
const seams = require(path.join(ROOT, 'src', 'module-seams.js'));
|
|
13
|
+
|
|
14
|
+
test('verifyPortsSatisfied: ok when every consumed port is provided', () => {
|
|
15
|
+
const manifests = [
|
|
16
|
+
{ key: 'economy', provides: ['reward'], consumes: [] },
|
|
17
|
+
{ key: 'grading', provides: ['grade'], consumes: [] },
|
|
18
|
+
{ key: 'lifecycle', provides: [], consumes: ['reward', 'grade'] },
|
|
19
|
+
];
|
|
20
|
+
const r = seams.verifyPortsSatisfied(manifests);
|
|
21
|
+
assert.equal(r.ok, true, r.errors.join('; '));
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('verifyPortsSatisfied: flags a consumed port with no provider', () => {
|
|
25
|
+
const r = seams.verifyPortsSatisfied([
|
|
26
|
+
{ key: 'lifecycle', provides: [], consumes: ['reward'] },
|
|
27
|
+
]);
|
|
28
|
+
assert.equal(r.ok, false);
|
|
29
|
+
assert.match(r.errors[0], /consumes port "reward" but no enabled module provides it/);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('verifyPortsSatisfied: flags a port with two providers', () => {
|
|
33
|
+
const r = seams.verifyPortsSatisfied([
|
|
34
|
+
{ key: 'a', provides: ['reward'], consumes: [] },
|
|
35
|
+
{ key: 'b', provides: ['reward'], consumes: [] },
|
|
36
|
+
]);
|
|
37
|
+
assert.equal(r.ok, false);
|
|
38
|
+
assert.match(r.errors.join('\n'), /provided by more than one enabled module/);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('verifyPortsSatisfied: empty / no-port manifests are ok', () => {
|
|
42
|
+
assert.equal(seams.verifyPortsSatisfied([]).ok, true);
|
|
43
|
+
assert.equal(seams.verifyPortsSatisfied([{ key: 'x', provides: [], consumes: [] }]).ok, true);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('emitAsync: awaits async listeners and isolates a rejecting one', async () => {
|
|
47
|
+
seams._reset();
|
|
48
|
+
const order = [];
|
|
49
|
+
seams.on('shipped', async (p) => { await Promise.resolve(); order.push(`a:${p}`); });
|
|
50
|
+
seams.on('shipped', async () => { throw new Error('async boom'); }); // isolated
|
|
51
|
+
seams.on('shipped', async (p) => { await Promise.resolve(); order.push(`c:${p}`); });
|
|
52
|
+
const invoked = await seams.emitAsync('shipped', 9);
|
|
53
|
+
assert.equal(invoked, 3);
|
|
54
|
+
assert.deepEqual(order, ['a:9', 'c:9']);
|
|
55
|
+
assert.equal(await seams.emitAsync('nobody', 1), 0);
|
|
56
|
+
seams._reset();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('snapshot reflects wired ports + event listeners', () => {
|
|
60
|
+
seams._reset();
|
|
61
|
+
seams.registerProvider('reward', () => 1);
|
|
62
|
+
seams.on('shipped', () => {});
|
|
63
|
+
seams.on('shipped', () => {});
|
|
64
|
+
const snap = seams.snapshot();
|
|
65
|
+
assert.deepEqual(snap.ports, ['reward']);
|
|
66
|
+
assert.deepEqual(snap.events, [{ event: 'shipped', listeners: 2 }]);
|
|
67
|
+
seams._reset();
|
|
68
|
+
});
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// tests/modules.mjs — the feature-module selection resolver (task 1193 / V4.R54, ADR 0062 §4).
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { test } from 'node:test';
|
|
4
|
+
import modulesMod from '../src/modules.js';
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
resolveModules, isModuleEnabled, enabledModules, enabledDisciplines, clientModules,
|
|
8
|
+
KNOWN_MODULES, MODULE_REGISTRY, loadModules,
|
|
9
|
+
} = modulesMod;
|
|
10
|
+
|
|
11
|
+
const VANILLA = {}; // no config at all
|
|
12
|
+
const OTB = { modules: { game: true, 'art-pipeline': true, discord: true, 'dev-box': true } };
|
|
13
|
+
// The post-extraction registry: built-ins (game, art-pipeline, discord) + every
|
|
14
|
+
// discovered module. dev-box now lives in modules/dev-box/ (BV1.R43), so it is a
|
|
15
|
+
// DISCOVERED key, not a built-in MODULE_REGISTRY one. The pure resolver tests
|
|
16
|
+
// below pass this effective registry so 'dev-box' is a known key — exactly what
|
|
17
|
+
// loadModules() does in production. Membership across the move is preserved here.
|
|
18
|
+
const EFFECTIVE = modulesMod.effectiveRegistry();
|
|
19
|
+
|
|
20
|
+
test('vanilla (no config) resolves every module OFF — fail-to-vanilla, never fail-to-OTB', () => {
|
|
21
|
+
const m = resolveModules({});
|
|
22
|
+
for (const k of KNOWN_MODULES) assert.equal(m[k], false, `${k} should default off`);
|
|
23
|
+
assert.deepEqual(enabledModules(m), []);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('every registry module has an explicit default of false', () => {
|
|
27
|
+
for (const k of KNOWN_MODULES) assert.equal(MODULE_REGISTRY[k].default, false);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('instance config turns modules on', () => {
|
|
31
|
+
const m = resolveModules({ neutral: VANILLA, instance: OTB, registry: EFFECTIVE });
|
|
32
|
+
assert.equal(m.game, true);
|
|
33
|
+
assert.equal(m['dev-box'], true);
|
|
34
|
+
assert.equal(isModuleEnabled('discord', m), true);
|
|
35
|
+
// memory (BV1.R72), grading (BV1.R73), economy (BV1.R77), ideas (BV1.R78),
|
|
36
|
+
// security (BV1.R79), builder-settings (BV1.R80), onboarding (BV1.R81),
|
|
37
|
+
// sessions (BV1.R82), autonomy (BV1.R83), status-ui (BV1.R84), and hall-ui
|
|
38
|
+
// (BV1.R85) are CORE-domain modules (ADR 0091/0093): unlike the opt-in feature
|
|
39
|
+
// modules, their manifests are `default: true`, so they resolve ON even though
|
|
40
|
+
// the OTB instance config doesn't list them (the build system's memory + quality
|
|
41
|
+
// gate + builder economy + idea inbox + red-team intake + prefs + onboarding +
|
|
42
|
+
// session corpus + the MAS autonomy machinery + the status dashboard + the
|
|
43
|
+
// builders' hall ship to every instance — see each module.json).
|
|
44
|
+
assert.deepEqual(enabledModules(m).sort(), ['art-pipeline', 'autonomy', 'builder-settings', 'dev-box', 'discord', 'economy', 'game', 'grading', 'hall-ui', 'ideas', 'lifecycle', 'memory', 'onboarding', 'security', 'sessions', 'status-ui']);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('instance config overrides the neutral starter per-flag (deep merge of the modules map)', () => {
|
|
48
|
+
const neutral = { modules: { game: false, discord: false, 'dev-box': false, 'art-pipeline': false } };
|
|
49
|
+
const instance = { modules: { discord: true } }; // only flip one
|
|
50
|
+
const m = resolveModules({ neutral, instance, registry: EFFECTIVE });
|
|
51
|
+
assert.equal(m.discord, true);
|
|
52
|
+
assert.equal(m.game, false); // neutral value survives
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('env override beats instance config (precedence), with prefix + snake-casing', () => {
|
|
56
|
+
const m = resolveModules({ instance: OTB, env: { OTB_MODULE_DEV_BOX: '0' }, envPrefix: 'OTB', registry: EFFECTIVE });
|
|
57
|
+
assert.equal(m['dev-box'], false); // env off beat instance on
|
|
58
|
+
assert.equal(m.game, true); // others untouched
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// env-override parsing is exercised against an explicit registry: the built-in
|
|
62
|
+
// MODULE_REGISTRY is now empty (every module — incl. game, BV1.R49 — lives on disk
|
|
63
|
+
// and is injected via the effective registry), so resolveModules only honors an
|
|
64
|
+
// env override for a key the passed registry KNOWS. Supply one with `game`.
|
|
65
|
+
const GAME_REG = { game: { default: false } };
|
|
66
|
+
|
|
67
|
+
test('env override accepts on/off/true/false/1/0 spellings', () => {
|
|
68
|
+
for (const v of ['on', 'true', '1', 'yes', 'enabled']) {
|
|
69
|
+
assert.equal(resolveModules({ env: { CLOUDBONGOS_MODULE_GAME: v }, registry: GAME_REG }).game, true, `${v} -> true`);
|
|
70
|
+
}
|
|
71
|
+
for (const v of ['off', 'false', '0', 'no', 'disabled']) {
|
|
72
|
+
assert.equal(resolveModules({ env: { CLOUDBONGOS_MODULE_GAME: v }, registry: GAME_REG }).game, false, `${v} -> false`);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('a garbage env value is rejected loudly (not silently coerced)', () => {
|
|
77
|
+
assert.throws(() => resolveModules({ env: { CLOUDBONGOS_MODULE_GAME: 'maybe' }, registry: GAME_REG }), /not a boolean/);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('an unknown module key in config is rejected when ENABLED (typo guard)', () => {
|
|
81
|
+
assert.throws(() => resolveModules({ instance: { modules: { gaem: true } } }), /unknown module "gaem"/);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// task 1824 — a stripped CORE has no game/art-pipeline/discord/dev-box, but the
|
|
85
|
+
// config/modules.neutral.json that SHIPS with it names them (so the same file is valid
|
|
86
|
+
// in the full repo). The loader must TOLERATE an unknown module when it is DISABLED, or
|
|
87
|
+
// a vanilla self-host crashes on `unknown module "game"`.
|
|
88
|
+
test('an unknown module key that is DISABLED is tolerated (a config may name a not-yet-installed module)', () => {
|
|
89
|
+
const reg = { memory: { default: true }, grading: { default: true } }; // core-only registry (no feature modules)
|
|
90
|
+
// The exact vanilla-core scenario: neutral names four absent feature modules, all off.
|
|
91
|
+
const neutral = { modules: { game: false, 'art-pipeline': false, discord: false, 'dev-box': false } };
|
|
92
|
+
let m;
|
|
93
|
+
assert.doesNotThrow(() => { m = resolveModules({ neutral, registry: reg }); });
|
|
94
|
+
assert.deepEqual(m, { memory: true, grading: true }); // core modules resolve; absent-disabled dropped
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('a DISABLED-but-absent module still throws if someone tries to ENABLE it', () => {
|
|
98
|
+
const reg = { memory: { default: true } };
|
|
99
|
+
assert.throws(
|
|
100
|
+
() => resolveModules({ instance: { modules: { game: true } }, registry: reg }),
|
|
101
|
+
/cannot enable unknown module "game"/,
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('isModuleEnabled throws on an unknown module name (programmer error)', () => {
|
|
106
|
+
assert.throws(() => isModuleEnabled('nope', resolveModules({})), /unknown module/);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('disciplines: vanilla offers engineer + ideator (core); art-pipeline adds artist (R59)', () => {
|
|
110
|
+
// Ideation is methodology core (idea_inbox / capture / triage ship to every
|
|
111
|
+
// instance), so it is offered with no modules on; only 'artist' is module-gated.
|
|
112
|
+
// art-pipeline is now a DISCOVERED module (BV1.R48), so pass EFFECTIVE registry.
|
|
113
|
+
assert.deepEqual(enabledDisciplines(resolveModules({})), ['engineer', 'ideator']);
|
|
114
|
+
const m = resolveModules({ instance: { modules: { 'art-pipeline': true } }, registry: EFFECTIVE });
|
|
115
|
+
assert.deepEqual(enabledDisciplines(m), ['engineer', 'ideator', 'artist']);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('clientModules is a safe boolean projection covering every known module + disciplines', () => {
|
|
119
|
+
const c = clientModules(resolveModules({ instance: OTB, registry: EFFECTIVE }));
|
|
120
|
+
for (const k of KNOWN_MODULES) assert.equal(typeof c.enabled[k], 'boolean');
|
|
121
|
+
assert.ok(Array.isArray(c.disciplines));
|
|
122
|
+
assert.ok(c.disciplines.includes('engineer'));
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('the resolved set is frozen (callers cannot mutate the singleton)', () => {
|
|
126
|
+
const m = resolveModules({ instance: OTB, registry: EFFECTIVE });
|
|
127
|
+
assert.throws(() => { m.game = false; }, TypeError);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test('the committed config files resolve: OTB enables all four, on disk', () => {
|
|
131
|
+
// loadModules reads config/modules.json over config/modules.neutral.json.
|
|
132
|
+
// No GDS_BRANDING_FILE → still the default OTB instance pack (regression guard
|
|
133
|
+
// for the GDS_MODULES_FILE selector below).
|
|
134
|
+
const m = loadModules({ env: {} });
|
|
135
|
+
assert.equal(m.game, true);
|
|
136
|
+
assert.equal(m['art-pipeline'], true);
|
|
137
|
+
assert.equal(m.discord, true);
|
|
138
|
+
assert.equal(m['dev-box'], true);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test('GDS_MODULES_FILE selects the instance modules pack on disk (mirrors GDS_BRANDING_FILE)', () => {
|
|
142
|
+
// Point explicitly at the neutral pack; it must win over the committed
|
|
143
|
+
// config/modules.json (which enables all four).
|
|
144
|
+
const m = loadModules({ env: { GDS_MODULES_FILE: 'config/modules.neutral.json' } });
|
|
145
|
+
for (const k of KNOWN_MODULES) assert.equal(m[k], false, `${k} should be off when GDS_MODULES_FILE → neutral`);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test('a branded sibling (GDS_BRANDING_FILE set, no GDS_MODULES_FILE) defaults to NEUTRAL, not OTB-all-on', () => {
|
|
149
|
+
// Regression for the cloudbongos.com bug (CB-V1 task 1, C8 proof): the vanilla
|
|
150
|
+
// Customer-0 process sets GDS_BRANDING_FILE but, lacking a modules selector,
|
|
151
|
+
// silently inherited OTB's config/modules.json → advertised all four modules ON.
|
|
152
|
+
// A non-default brand must fall through to the neutral (all-off) module set.
|
|
153
|
+
const m = loadModules({ env: { GDS_BRANDING_FILE: 'config/branding.cloudbongos.json' } });
|
|
154
|
+
for (const k of KNOWN_MODULES) assert.equal(m[k], false, `${k} must be off for a branded sibling`);
|
|
155
|
+
assert.deepEqual(enabledDisciplines(m), ['engineer', 'ideator']);
|
|
156
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// tests/modules_route.mjs — the hall "Modules" tab backend (ADR 0107 §9,
|
|
2
|
+
// task 1776). listModules() is fs-only (the loader's disk scan + branding
|
|
3
|
+
// read, no DB), so it's safe to exercise directly against the real repo tree —
|
|
4
|
+
// the same shape tests/modules.mjs and tests/atlas.mjs already rely on.
|
|
5
|
+
import assert from 'node:assert/strict';
|
|
6
|
+
import { test } from 'node:test';
|
|
7
|
+
import { createRequire } from 'node:module';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
|
|
11
|
+
const require = createRequire(import.meta.url);
|
|
12
|
+
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
13
|
+
const { listModules } = require(path.join(ROOT, 'src', 'bongos', 'routes', 'modules.js'));
|
|
14
|
+
|
|
15
|
+
test('listModules: every on-disk module is present, sorted, and well-formed', () => {
|
|
16
|
+
const rows = listModules();
|
|
17
|
+
assert.ok(rows.length >= 18, `expected every on-disk module (got ${rows.length})`);
|
|
18
|
+
for (const m of rows) {
|
|
19
|
+
assert.equal(typeof m.key, 'string');
|
|
20
|
+
assert.ok(['own', 'core'].includes(m.provenance), `${m.key}: provenance is own|core`);
|
|
21
|
+
assert.equal(typeof m.enabled, 'boolean');
|
|
22
|
+
}
|
|
23
|
+
const keys = rows.map((m) => m.key);
|
|
24
|
+
assert.deepEqual(keys, [...keys].sort(), 'listModules is sorted by key');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('listModules: today, every module is own-built (ADR 0107 audit — no module names a foreign origin yet)', () => {
|
|
28
|
+
const rows = listModules();
|
|
29
|
+
for (const m of rows) assert.equal(m.provenance, 'own', `${m.key} unexpectedly classifies core-loaded`);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('listModules: game module is on-disk, enabled in the OTB instance config, and carries no origin', () => {
|
|
33
|
+
const rows = listModules();
|
|
34
|
+
const game = rows.find((m) => m.key === 'game');
|
|
35
|
+
assert.ok(game, 'game module discovered');
|
|
36
|
+
assert.equal(game.enabled, true);
|
|
37
|
+
assert.equal(game.origin, null);
|
|
38
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// tests/newcomer_floor.mjs
|
|
2
|
+
//
|
|
3
|
+
// CI shim (task 1158): run-unit-tests.js only scans tests/*.mjs, so the
|
|
4
|
+
// newcomer-floor replenisher's pure-helper suite (deficit math, monotonic
|
|
5
|
+
// per-instance seq, template->copy scope-clamp, real templates.json integrity)
|
|
6
|
+
// would never run in the gate. This requires the co-located suite so it does.
|
|
7
|
+
//
|
|
8
|
+
// DB-free: the helpers are pure and loadTemplates() reads only the committed
|
|
9
|
+
// newcomer-floor.templates.json — no network, no Postgres. Belongs in the unit
|
|
10
|
+
// gate (NOT the integration set).
|
|
11
|
+
//
|
|
12
|
+
// Run: node tests/newcomer_floor.mjs
|
|
13
|
+
import { createRequire } from 'node:module';
|
|
14
|
+
const require = createRequire(import.meta.url);
|
|
15
|
+
// Executing the co-located test runs every assertion; it process.exit(1)s on the
|
|
16
|
+
// first failure and prints a success line otherwise — exactly the gate contract.
|
|
17
|
+
require('../scripts/gds/newcomer-floor.test.js');
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// tests/newcomer_restock.mjs
|
|
2
|
+
//
|
|
3
|
+
// Pure-helper + skip-path tests for the on-claim newcomer-chore restock
|
|
4
|
+
// (src/bongos/newcomer-restock.js, task 1168). DB-free: requiring the module loads
|
|
5
|
+
// db.js (its pg pool is lazy — no connection on import), and every assertion
|
|
6
|
+
// below exercises either a pure helper or the restockForClaim SKIP path, which
|
|
7
|
+
// returns before any query. The DB-touching restock is verified functionally
|
|
8
|
+
// post-deploy, not here.
|
|
9
|
+
//
|
|
10
|
+
// Run: node tests/newcomer_restock.mjs
|
|
11
|
+
|
|
12
|
+
import { strict as assert } from 'node:assert';
|
|
13
|
+
import { createRequire } from 'node:module';
|
|
14
|
+
|
|
15
|
+
const require = createRequire(import.meta.url);
|
|
16
|
+
const r = require('../modules/onboarding/newcomer-restock.js');
|
|
17
|
+
|
|
18
|
+
let passed = 0;
|
|
19
|
+
function t(name, fn) {
|
|
20
|
+
try { fn(); passed += 1; console.log(` PASS ${name}`); }
|
|
21
|
+
catch (e) { console.log(` FAIL ${name}\n ${e.message}`); process.exit(1); }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// ---- parseSeq ----
|
|
25
|
+
t('parseSeq: matches discipline+template, rejects others', () => {
|
|
26
|
+
assert.equal(r.parseSeq('tmpl:engineer:docs-hygiene-pass:5', 'engineer', 'docs-hygiene-pass'), 5);
|
|
27
|
+
assert.equal(r.parseSeq('tmpl:engineer:docs-hygiene-pass:5', 'artist', 'docs-hygiene-pass'), null);
|
|
28
|
+
assert.equal(r.parseSeq('tmpl:engineer:other:5', 'engineer', 'docs-hygiene-pass'), null);
|
|
29
|
+
assert.equal(r.parseSeq('manual:engineer:x', 'engineer', 'docs-hygiene-pass'), null);
|
|
30
|
+
assert.equal(r.parseSeq('tmpl:engineer:docs-hygiene-pass:nope', 'engineer', 'docs-hygiene-pass'), null);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// ---- buildDescription ----
|
|
34
|
+
t('buildDescription: folds done-when + "always one waiting" footer', () => {
|
|
35
|
+
const d = r.buildDescription({ description: 'Body.', done_when: ['x', 'y'] });
|
|
36
|
+
assert.ok(d.includes('Body.'));
|
|
37
|
+
assert.ok(d.includes('**Done when:**') && d.includes('- x') && d.includes('- y'));
|
|
38
|
+
assert.ok(d.includes('there is always one waiting'), 'restock footer present');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// ---- templateIdFromRef ----
|
|
42
|
+
t('templateIdFromRef: extracts the template_id, honouring the discipline', () => {
|
|
43
|
+
assert.equal(r.templateIdFromRef('tmpl:engineer:unit-test-pass:3', 'engineer'), 'unit-test-pass');
|
|
44
|
+
assert.equal(r.templateIdFromRef('tmpl:engineer:unit-test-pass:3', 'artist'), null, 'discipline mismatch');
|
|
45
|
+
assert.equal(r.templateIdFromRef('manual:engineer:x', 'engineer'), null, 'non-chore ref');
|
|
46
|
+
assert.equal(r.templateIdFromRef('tmpl:engineer:unit-test-pass', 'engineer'), null, 'too few parts');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// ---- loadTemplates: real templates.json (per-discipline LIST since task 1488) ----
|
|
50
|
+
t('loadTemplates: real file is a per-discipline list of valid chores', () => {
|
|
51
|
+
const tmpl = r.loadTemplates();
|
|
52
|
+
for (const disc of ['engineer', 'artist', 'ideator']) {
|
|
53
|
+
assert.ok(Array.isArray(tmpl[disc]) && tmpl[disc].length >= 1, `${disc} is a non-empty list`);
|
|
54
|
+
for (const c of tmpl[disc]) {
|
|
55
|
+
assert.ok(c.template_id && c.version_id && c.title, `${disc}/${c.template_id || '?'} has id/version/title`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const engIds = tmpl.engineer.map((c) => c.template_id);
|
|
59
|
+
assert.ok(engIds.includes('unit-test-pass') && engIds.includes('docs-hygiene-pass'),
|
|
60
|
+
`engineer offers the unit-test chore + the docs sweep (got ${engIds.join(', ')})`);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// ---- loadFloors: real config, floor >= 2 so one is always left on claim ----
|
|
64
|
+
t('loadFloors: real config keeps floor >= 2 per discipline (a spare on every claim)', () => {
|
|
65
|
+
const f = r.loadFloors();
|
|
66
|
+
for (const disc of ['engineer', 'artist', 'ideator']) {
|
|
67
|
+
assert.ok(f[disc] >= 2, `${disc} floor ${f[disc]} must be >= 2 so one remains the instant one is claimed`);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// ---- restockForClaim: skip path is DB-free (awaited) ----
|
|
72
|
+
// (returns an array of per-template results; the skip path is a 1-element array.)
|
|
73
|
+
assert.deepEqual(await r.restockForClaim(null), [{ skipped: true }]);
|
|
74
|
+
assert.deepEqual(await r.restockForClaim({ source: 'auto-newcomer-floor-ai', discipline: 'engineer' }), [{ skipped: true }]);
|
|
75
|
+
assert.deepEqual(await r.restockForClaim({ source: 'newcomer-floor-manual', discipline: 'artist' }), [{ skipped: true }]);
|
|
76
|
+
assert.deepEqual(await r.restockForClaim({ source: 'newcomer-template', discipline: 'bogus' }), [{ skipped: true }]);
|
|
77
|
+
passed += 1;
|
|
78
|
+
console.log(' PASS restockForClaim: non-chore tasks skipped without touching the DB');
|
|
79
|
+
|
|
80
|
+
console.log(`\n✓ all ${passed} newcomer-restock tests passed`);
|