@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,195 @@
|
|
|
1
|
+
// src/bongos/middleware/rate-limit.js — V3.R34 (#255).
|
|
2
|
+
//
|
|
3
|
+
// Two sliding-window in-memory limiters that protect write methods on
|
|
4
|
+
// /api/gds/*. Read methods (GET, HEAD, OPTIONS) bypass entirely.
|
|
5
|
+
//
|
|
6
|
+
// 1. Per-IP limiter — 30 writes / 60s. Anchors on req.ip (which honors
|
|
7
|
+
// 'trust proxy' in server.js so Cloudflare's
|
|
8
|
+
// X-Forwarded-For is what counts). Catches
|
|
9
|
+
// unauthenticated abuse and stolen-token replay
|
|
10
|
+
// from a single source.
|
|
11
|
+
//
|
|
12
|
+
// 2. Per-session limiter — 60 writes / 60s, keyed on the bearer token (or
|
|
13
|
+
// session cookie) if present. Catches a runaway
|
|
14
|
+
// authenticated script that's spreading writes
|
|
15
|
+
// across multiple IPs.
|
|
16
|
+
//
|
|
17
|
+
// 3. Public-read limiter — 120 reads / 60s per IP, applied ONLY to the
|
|
18
|
+
// unauthenticated /public/* surface (mounted there by
|
|
19
|
+
// routes/public.js, NOT globally — the two write
|
|
20
|
+
// limiters above bypass reads by design). It exists
|
|
21
|
+
// because /public/uptime + /public/repo-health run
|
|
22
|
+
// multi-row 90-day aggregates on every uncached call,
|
|
23
|
+
// so the surface is a DoS / cost-amplification target
|
|
24
|
+
// (red-team #604 / task 1035). 120/min clears a legit
|
|
25
|
+
// dashboard load (~13 /public/* fetches per page, and
|
|
26
|
+
// browsers honor the routes' Cache-Control so they
|
|
27
|
+
// don't re-fetch within the window) with wide margin,
|
|
28
|
+
// while capping a cache-ignoring scraper at ~2 req/s.
|
|
29
|
+
// Keyed on req.ip — the SAME real-client-IP resolution
|
|
30
|
+
// as the per-IP write limiter: Caddy trusts the
|
|
31
|
+
// Cloudflare ranges and forwards the client IP, and
|
|
32
|
+
// server.js sets 'trust proxy', so req.ip is the end
|
|
33
|
+
// user, not Cloudflare's single origin IP.
|
|
34
|
+
//
|
|
35
|
+
// Any limiter tripping → 429 with Retry-After (seconds rounded up to the
|
|
36
|
+
// nearest whole second). Audit middleware still fires on a write 429 — the row
|
|
37
|
+
// in audit_log is forensic value for "who tried too hard." (Reads are never
|
|
38
|
+
// audit-logged, by the GET-skip rule, so a public-read 429 is not recorded.)
|
|
39
|
+
//
|
|
40
|
+
// Storage: a Map of {key → timestamp[]}. Each request walks the array, drops
|
|
41
|
+
// timestamps older than the window, then either pushes the new one (allow)
|
|
42
|
+
// or returns 429 (deny). O(window-size) per request. We sweep the whole Map
|
|
43
|
+
// once per SWEEP_MS to keep memory bounded under load.
|
|
44
|
+
//
|
|
45
|
+
// In-memory means a process restart wipes the windows — which is fine; a
|
|
46
|
+
// burst tracked across restarts is a different kind of problem (we have
|
|
47
|
+
// audit_log + dep-scan for that). The cost of "we forget after a restart"
|
|
48
|
+
// is far cheaper than wiring an external store like Redis for a single-node
|
|
49
|
+
// deployment.
|
|
50
|
+
|
|
51
|
+
const PER_IP_WINDOW_MS = 60 * 1000;
|
|
52
|
+
const PER_IP_LIMIT = 30;
|
|
53
|
+
const PER_SESSION_WINDOW_MS = 60 * 1000;
|
|
54
|
+
const PER_SESSION_LIMIT = 60;
|
|
55
|
+
const PUBLIC_READ_WINDOW_MS = 60 * 1000;
|
|
56
|
+
const PUBLIC_READ_LIMIT = 120;
|
|
57
|
+
const SWEEP_MS = 5 * 60 * 1000;
|
|
58
|
+
|
|
59
|
+
const ipBuckets = new Map();
|
|
60
|
+
const sessionBuckets = new Map();
|
|
61
|
+
const publicReadBuckets = new Map();
|
|
62
|
+
|
|
63
|
+
const WRITE_METHODS = new Set(['POST', 'PATCH', 'PUT', 'DELETE']);
|
|
64
|
+
// HEAD is metered too: Express runs the GET handler (incl. the DB query) for a
|
|
65
|
+
// HEAD, so it carries the same cost as the GET. OPTIONS never reaches this
|
|
66
|
+
// limiter — the public router answers CORS preflights and returns 204 first.
|
|
67
|
+
const READ_METHODS = new Set(['GET', 'HEAD']);
|
|
68
|
+
|
|
69
|
+
function pruneAndCount(bucket, now, windowMs) {
|
|
70
|
+
const cutoff = now - windowMs;
|
|
71
|
+
// arr is the in-place timestamps array; trim in place.
|
|
72
|
+
let i = 0;
|
|
73
|
+
while (i < bucket.length && bucket[i] < cutoff) i++;
|
|
74
|
+
if (i > 0) bucket.splice(0, i);
|
|
75
|
+
return bucket.length;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function extractSessionKey(req) {
|
|
79
|
+
// Bearer token first (CLI flow); cookie second (web flow). We use the
|
|
80
|
+
// token AS-IS as the limiter key — it's already opaque + cheap to hash to
|
|
81
|
+
// its column in the Map. The token never leaves this process.
|
|
82
|
+
const authHeader = req.headers && req.headers.authorization;
|
|
83
|
+
if (authHeader && /^Bearer\s+/.test(authHeader)) {
|
|
84
|
+
return 'b:' + authHeader.replace(/^Bearer\s+/, '').trim();
|
|
85
|
+
}
|
|
86
|
+
const cookie = req.headers && req.headers.cookie;
|
|
87
|
+
if (cookie) {
|
|
88
|
+
const m = /(?:^|;\s*)(?:gds_session|pms_session)=([^;]+)/.exec(cookie);
|
|
89
|
+
if (m) return 'c:' + m[1];
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function sweep() {
|
|
95
|
+
const now = Date.now();
|
|
96
|
+
for (const [k, arr] of ipBuckets) {
|
|
97
|
+
pruneAndCount(arr, now, PER_IP_WINDOW_MS);
|
|
98
|
+
if (arr.length === 0) ipBuckets.delete(k);
|
|
99
|
+
}
|
|
100
|
+
for (const [k, arr] of sessionBuckets) {
|
|
101
|
+
pruneAndCount(arr, now, PER_SESSION_WINDOW_MS);
|
|
102
|
+
if (arr.length === 0) sessionBuckets.delete(k);
|
|
103
|
+
}
|
|
104
|
+
for (const [k, arr] of publicReadBuckets) {
|
|
105
|
+
pruneAndCount(arr, now, PUBLIC_READ_WINDOW_MS);
|
|
106
|
+
if (arr.length === 0) publicReadBuckets.delete(k);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Schedule the sweep. unref() so it doesn't keep the process alive during
|
|
111
|
+
// graceful shutdown in tests.
|
|
112
|
+
const sweepTimer = setInterval(sweep, SWEEP_MS);
|
|
113
|
+
if (typeof sweepTimer.unref === 'function') sweepTimer.unref();
|
|
114
|
+
|
|
115
|
+
function rateLimitMiddleware(req, res, next) {
|
|
116
|
+
if (!WRITE_METHODS.has(req.method)) return next();
|
|
117
|
+
|
|
118
|
+
const now = Date.now();
|
|
119
|
+
|
|
120
|
+
// --- per-IP ---
|
|
121
|
+
const ip = req.ip || req.socket?.remoteAddress || 'unknown';
|
|
122
|
+
let ipBucket = ipBuckets.get(ip);
|
|
123
|
+
if (!ipBucket) { ipBucket = []; ipBuckets.set(ip, ipBucket); }
|
|
124
|
+
const ipCount = pruneAndCount(ipBucket, now, PER_IP_WINDOW_MS);
|
|
125
|
+
if (ipCount >= PER_IP_LIMIT) {
|
|
126
|
+
const oldest = ipBucket[0];
|
|
127
|
+
const retryAfter = Math.max(1, Math.ceil((oldest + PER_IP_WINDOW_MS - now) / 1000));
|
|
128
|
+
res.set('Retry-After', String(retryAfter));
|
|
129
|
+
res.set('X-RateLimit-Scope', 'per-ip');
|
|
130
|
+
res.set('X-RateLimit-Limit', String(PER_IP_LIMIT));
|
|
131
|
+
res.set('X-RateLimit-Window-Seconds', String(PER_IP_WINDOW_MS / 1000));
|
|
132
|
+
return res.fail('rate_limited', 429, { scope: 'per-ip', retry_after_seconds: retryAfter });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// --- per-session ---
|
|
136
|
+
const sessionKey = extractSessionKey(req);
|
|
137
|
+
if (sessionKey) {
|
|
138
|
+
let sBucket = sessionBuckets.get(sessionKey);
|
|
139
|
+
if (!sBucket) { sBucket = []; sessionBuckets.set(sessionKey, sBucket); }
|
|
140
|
+
const sCount = pruneAndCount(sBucket, now, PER_SESSION_WINDOW_MS);
|
|
141
|
+
if (sCount >= PER_SESSION_LIMIT) {
|
|
142
|
+
const oldest = sBucket[0];
|
|
143
|
+
const retryAfter = Math.max(1, Math.ceil((oldest + PER_SESSION_WINDOW_MS - now) / 1000));
|
|
144
|
+
res.set('Retry-After', String(retryAfter));
|
|
145
|
+
res.set('X-RateLimit-Scope', 'per-session');
|
|
146
|
+
res.set('X-RateLimit-Limit', String(PER_SESSION_LIMIT));
|
|
147
|
+
res.set('X-RateLimit-Window-Seconds', String(PER_SESSION_WINDOW_MS / 1000));
|
|
148
|
+
return res.fail('rate_limited', 429, { scope: 'per-session', retry_after_seconds: retryAfter });
|
|
149
|
+
}
|
|
150
|
+
sBucket.push(now);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// record the allow on the IP bucket
|
|
154
|
+
ipBucket.push(now);
|
|
155
|
+
next();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Per-IP read limiter for the unauthenticated /public/* surface. Mounted by
|
|
159
|
+
// routes/public.js scoped to '/public' (NOT globally), so it only ever sees
|
|
160
|
+
// public reads — the global rateLimitMiddleware above still bypasses reads
|
|
161
|
+
// everywhere else. See limiter #3 in the header comment for the rationale.
|
|
162
|
+
function publicReadRateLimitMiddleware(req, res, next) {
|
|
163
|
+
// Only meter reads. There are no write routes under /public; if one is ever
|
|
164
|
+
// added it falls through to the global write limiter, so pass it along here.
|
|
165
|
+
if (!READ_METHODS.has(req.method)) return next();
|
|
166
|
+
|
|
167
|
+
const now = Date.now();
|
|
168
|
+
const ip = req.ip || req.socket?.remoteAddress || 'unknown';
|
|
169
|
+
let bucket = publicReadBuckets.get(ip);
|
|
170
|
+
if (!bucket) { bucket = []; publicReadBuckets.set(ip, bucket); }
|
|
171
|
+
const count = pruneAndCount(bucket, now, PUBLIC_READ_WINDOW_MS);
|
|
172
|
+
if (count >= PUBLIC_READ_LIMIT) {
|
|
173
|
+
const oldest = bucket[0];
|
|
174
|
+
const retryAfter = Math.max(1, Math.ceil((oldest + PUBLIC_READ_WINDOW_MS - now) / 1000));
|
|
175
|
+
res.set('Retry-After', String(retryAfter));
|
|
176
|
+
res.set('X-RateLimit-Scope', 'public-read');
|
|
177
|
+
res.set('X-RateLimit-Limit', String(PUBLIC_READ_LIMIT));
|
|
178
|
+
res.set('X-RateLimit-Window-Seconds', String(PUBLIC_READ_WINDOW_MS / 1000));
|
|
179
|
+
return res.fail('rate_limited', 429, { scope: 'public-read', retry_after_seconds: retryAfter });
|
|
180
|
+
}
|
|
181
|
+
bucket.push(now);
|
|
182
|
+
next();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
module.exports = {
|
|
186
|
+
rateLimitMiddleware,
|
|
187
|
+
publicReadRateLimitMiddleware,
|
|
188
|
+
// exported for tests + the security-baseline-check script
|
|
189
|
+
PER_IP_WINDOW_MS,
|
|
190
|
+
PER_IP_LIMIT,
|
|
191
|
+
PER_SESSION_WINDOW_MS,
|
|
192
|
+
PER_SESSION_LIMIT,
|
|
193
|
+
PUBLIC_READ_WINDOW_MS,
|
|
194
|
+
PUBLIC_READ_LIMIT,
|
|
195
|
+
};
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
// module-scope-map.js — the module → path-globs + `protected` roster (BV1.R54, ADR 0086 §4).
|
|
2
|
+
//
|
|
3
|
+
// This is the SOURCE OF THE SCOPE WALL for the goal-scoped work hierarchy. A goal
|
|
4
|
+
// is scoped to a set of modules; this map says (a) which file paths each module
|
|
5
|
+
// owns — the territory a goal member may author tasks within (consumed by the
|
|
6
|
+
// scope-subset check, BV1.R59 / goal-scope-check.js, via touchesOverlap) — and
|
|
7
|
+
// (b) whether that module is `protected` (its territory intersects the trust /
|
|
8
|
+
// ship-pipeline / migration / authz core), which makes creating a goal scoped to
|
|
9
|
+
// it Archon-only (BV1.R57 / POST /goals).
|
|
10
|
+
//
|
|
11
|
+
// TWO HARD RULES (ADR 0086 §7; the SEC #863 "second list that drifts" failure mode):
|
|
12
|
+
// 1. `protected` is DERIVED, never hand-set — a module is protected iff its
|
|
13
|
+
// globs overlap PROTECTED_GLOBS, the SINGLE source in permission-path-check.js.
|
|
14
|
+
// 2. We IMPORT PROTECTED_GLOBS; we never re-declare it. A fitness check
|
|
15
|
+
// (scripts/gds/fitness.js) reds the build if this file re-declares it.
|
|
16
|
+
//
|
|
17
|
+
// GLOB FORMAT = the touches[] convention (path-match.js): an exact path matches
|
|
18
|
+
// one file; a trailing '/' covers the whole subtree. No '*'/'**' wildcards — the
|
|
19
|
+
// goal scope-subset check is touchesOverlap (prefix-aware both directions), not a
|
|
20
|
+
// regex, so wildcards would never match. Every PROTECTED_GLOBS entry is likewise
|
|
21
|
+
// an exact path or dir-prefix, so the overlap is exact.
|
|
22
|
+
//
|
|
23
|
+
// FIRST CUT, auto-tightening. We are mid-strangler (ADR 0083): only dev-box has
|
|
24
|
+
// moved into modules/<key>/; the rest still live fused in src/bongos/. So a module's
|
|
25
|
+
// globs list WHERE ITS CODE LIVES TODAY plus its modules/<key>/ home, and the
|
|
26
|
+
// `protected` result reflects the current tree (most core domains are protected
|
|
27
|
+
// because their routes still sit under the blanket-protected src/bongos/routes/).
|
|
28
|
+
// As ADR 0083 moves a module's code into modules/<key>/, edit its globs here —
|
|
29
|
+
// the carve precedes the feature (ADR 0086 §4). The roster is the decided ~16
|
|
30
|
+
// modules + kernel from docs/design/modular-architecture/02-module-map.md §6.
|
|
31
|
+
//
|
|
32
|
+
// RELATION to src/modules.js: that registry tracks only the OPTIONAL feature
|
|
33
|
+
// modules (game/art-pipeline/discord/dev-box) an instance toggles. This map is a
|
|
34
|
+
// SUPERSET — every module including the always-on core domains — because the goal
|
|
35
|
+
// scope wall must place ALL work, not just the optional features.
|
|
36
|
+
|
|
37
|
+
'use strict';
|
|
38
|
+
|
|
39
|
+
const { PROTECTED_GLOBS } = require('./permission-path-check');
|
|
40
|
+
const { touchesOverlap } = require('./path-match');
|
|
41
|
+
|
|
42
|
+
// key → the path globs that constitute the module's code (exact paths or
|
|
43
|
+
// trailing-'/' subtree prefixes). See the header for the auto-tighten contract.
|
|
44
|
+
const MODULE_GLOBS = {
|
|
45
|
+
// --- the trust kernel: auth, rank, db pool, loader, seam registry, audit,
|
|
46
|
+
// config/identity, the route mount table, the server entrypoint ---
|
|
47
|
+
kernel: [
|
|
48
|
+
'src/bongos/auth.js', 'src/bongos/db.js', 'src/bongos/db-kernel.js', 'src/bongos/pool.js',
|
|
49
|
+
'src/bongos/routes.js', 'src/bongos/route-rank-check.js',
|
|
50
|
+
'src/bongos/permission-path-check.js', 'src/bongos/sensitive-surfaces.js',
|
|
51
|
+
'src/bongos/middleware/', 'src/bongos/live-channel.js', 'src/bongos/secret-box.js',
|
|
52
|
+
'src/bongos/repo-info.js', 'src/bongos/api-path-404.js', 'src/bongos/serve-internal.js',
|
|
53
|
+
'src/bongos/module-scope-map.js', 'src/bongos/hierarchy-config.js',
|
|
54
|
+
'src/instance-config.js', 'src/branding.js', 'src/modules.js',
|
|
55
|
+
'src/module-api.js', 'src/module-loader/',
|
|
56
|
+
// security-the-PROPERTY: the threat-model (/security/adr) + Archon-only
|
|
57
|
+
// exploit-detail engagement-doc store (/security/docs). Stays kernel when the
|
|
58
|
+
// red-team FEATURE carved to modules/security/ (BV1.R79 / 02-module-map §5).
|
|
59
|
+
'src/bongos/routes/security.js',
|
|
60
|
+
'server.js', 'config/',
|
|
61
|
+
],
|
|
62
|
+
// --- the build state machine + ship/grade/deploy orchestration + schema ---
|
|
63
|
+
// Carved into modules/lifecycle/ (BV1.R86 / ADR 0093 §1,§3): the task/claim/
|
|
64
|
+
// version/goal/done-when/dependency/gate-approvals routes + the db slice, the
|
|
65
|
+
// task-classifier + hierarchy + done-when libs, github-push + ship-card +
|
|
66
|
+
// ship-preflight + merge-lock + conflict-resolve + publish-reconciler +
|
|
67
|
+
// version-close, and the `lifecycle` kernel PORT — all under the
|
|
68
|
+
// modules/lifecycle/ glob. The db.js RESIDUE (kernel identity/auth/twin/leak)
|
|
69
|
+
// stays under the kernel key. The lifecycle CLIs travel with the domain but stay
|
|
70
|
+
// under scripts/; `migrations/` stays here (the schema is lifecycle territory for
|
|
71
|
+
// goal-scope/task-affinity).
|
|
72
|
+
lifecycle: [
|
|
73
|
+
'modules/lifecycle/',
|
|
74
|
+
'scripts/gds/ship.js', 'scripts/gds/claim.js', 'scripts/gds/release.js',
|
|
75
|
+
'scripts/gds/merge-mode.js', 'scripts/gds/confirm.js', 'scripts/gds/main-audit.js',
|
|
76
|
+
'scripts/gds/gate-review.js', 'scripts/gds/push-main.js', 'scripts/gds/ci-grade.js',
|
|
77
|
+
'scripts/gds/merge-lock.js', 'scripts/gds/version-close.js',
|
|
78
|
+
'migrations/',
|
|
79
|
+
],
|
|
80
|
+
// --- credit-allocation model + ledger + pricing + gamification ---
|
|
81
|
+
economy: [
|
|
82
|
+
// Carved into modules/economy/ (BV1.R77 / ADR 0093 §1-2): credits, cost,
|
|
83
|
+
// streak, achievements, leaderboard + the `reward` kernel PORT. llm-pricing.js
|
|
84
|
+
// stays core shared LLM-cost infra (doorway leak `llmPricing`, like llm-cache.js).
|
|
85
|
+
'src/bongos/llm-pricing.js',
|
|
86
|
+
'modules/economy/',
|
|
87
|
+
],
|
|
88
|
+
// --- grade-a-diff adversarial panel (the `grade` kernel PORT — BV1.R73) ---
|
|
89
|
+
grading: [
|
|
90
|
+
// grader.js + grader-workers/ + grader-rubric.json carved to modules/grading/
|
|
91
|
+
// (BV1.R73, ADR 0091 §4). cascade-dispatch.js stays a CORE lib (dormant
|
|
92
|
+
// System 3; its deps are lifecycle + builder-settings, not the grader — see
|
|
93
|
+
// modules/grading/CLAUDE.md "NOT in this module"); grade-smoke is its CLI.
|
|
94
|
+
'modules/grading/',
|
|
95
|
+
'src/bongos/cascade-dispatch.js', 'scripts/gds/grade-smoke.js',
|
|
96
|
+
],
|
|
97
|
+
// --- memory, recall, search, learnings ---
|
|
98
|
+
memory: [
|
|
99
|
+
// Carved into modules/memory/ (BV1.R72 / ADR 0091 §2); the memory-owned CLIs
|
|
100
|
+
// stay under scripts/gds/ (a command travels with its domain — design 02§1).
|
|
101
|
+
'modules/memory/',
|
|
102
|
+
'scripts/gds/recall.js', 'scripts/gds/learning-capture.js',
|
|
103
|
+
'scripts/gds/search-ingest-md.js', 'scripts/gds/search-ingest-db.js',
|
|
104
|
+
],
|
|
105
|
+
// --- admission, setup, newcomer floor ---
|
|
106
|
+
// Carved into modules/onboarding/ (BV1.R81 / ADR 0093 §1): the friction
|
|
107
|
+
// analyzer + onboarding state machine + newcomer-restock + the access-request
|
|
108
|
+
// admission routes + approval-broadcast + their db slice + the `onboarding`
|
|
109
|
+
// kernel PORT all moved (covered by the modules/onboarding/ glob). The core
|
|
110
|
+
// lifecycle (db.js claim/ship), auth callbacks, and the me/builders profile
|
|
111
|
+
// readers resolve the port — they stay in core (kernel / builder-settings).
|
|
112
|
+
// The onboarding-domain CLIs travel with the domain but stay under scripts/.
|
|
113
|
+
onboarding: [
|
|
114
|
+
'modules/onboarding/',
|
|
115
|
+
'scripts/gds/setup.js', 'scripts/gds/onboarding-config.js',
|
|
116
|
+
'scripts/gds/onboarding-analyze.js', 'scripts/gds/newcomer-floor.js',
|
|
117
|
+
],
|
|
118
|
+
// --- inbox, capture, triage, blockers (carved → modules/ideas/, BV1.R78) ---
|
|
119
|
+
ideas: [
|
|
120
|
+
'modules/ideas/',
|
|
121
|
+
'scripts/gds/capture.js', 'scripts/gds/triage.js', 'scripts/gds/render-ideas.js',
|
|
122
|
+
],
|
|
123
|
+
// --- builder prefs (wandering/skill/sound/render) + builder-needs ---
|
|
124
|
+
// Carved into modules/builder-settings/ (BV1.R80 / ADR 0093 §1): the five pref
|
|
125
|
+
// libs + builder-needs + their db slice + the `/me/*-prefs` routes + the
|
|
126
|
+
// `builder-settings` kernel PORT. The `GET /me` aggregator stays a thin core
|
|
127
|
+
// facade (routes/me.js) resolving that port — listed for task affinity. The
|
|
128
|
+
// pref-mirroring CLIs travel with the domain but stay under scripts/.
|
|
129
|
+
'builder-settings': [
|
|
130
|
+
'src/bongos/routes/me.js',
|
|
131
|
+
'scripts/gds/fetch-sound-prefs.js',
|
|
132
|
+
'modules/builder-settings/',
|
|
133
|
+
],
|
|
134
|
+
// --- session records, cost/eval/digest, transcript corpus, BFG ---
|
|
135
|
+
// Carved into modules/sessions/ (BV1.R82 / ADR 0093 §1): bfg.js + pulse.js +
|
|
136
|
+
// routes/sessions.js + the session_records db slice all moved (covered by the
|
|
137
|
+
// modules/sessions/ glob). The session-domain CLIs travel with the domain but
|
|
138
|
+
// stay under scripts/ (session-eval.js keeps its sibling read of
|
|
139
|
+
// modules/builder-settings/wandering-prefs — scripts are outside the kernel
|
|
140
|
+
// boundary, so it's not a cross-module import).
|
|
141
|
+
sessions: [
|
|
142
|
+
'scripts/gds/session.js', 'scripts/gds/session-cost.js', 'scripts/gds/session-eval.js',
|
|
143
|
+
'scripts/gds/session-digest.js', 'scripts/gds/backfill-sessions.js',
|
|
144
|
+
'scripts/gds/bfg-principal-token.js', 'scripts/gds/pulse.js',
|
|
145
|
+
'scripts/gds/repo-metrics.js',
|
|
146
|
+
'modules/sessions/',
|
|
147
|
+
],
|
|
148
|
+
// --- conductor dispatch, architect audits, autonomy gate, routine timers ---
|
|
149
|
+
// Carved into modules/autonomy/ (BV1.R83 / ADR 0093 §1): the autonomy_runs db
|
|
150
|
+
// slice + the routine-timers poller + the precheck route moved (covered by the
|
|
151
|
+
// modules/autonomy/ glob). The MAS-domain CLIs (gate / conductor / architect /
|
|
152
|
+
// run-routine) travel with the domain but stay under scripts/ (a command travels
|
|
153
|
+
// with its domain — design 02§1), as do the scheduled-task SKILL.md files.
|
|
154
|
+
autonomy: [
|
|
155
|
+
'modules/autonomy/',
|
|
156
|
+
'scripts/gds/autonomy-gate.js',
|
|
157
|
+
'scripts/gds/conductor-dispatch.js', 'scripts/gds/architect-audit.js',
|
|
158
|
+
'scripts/gds/run-routine.js', '.claude/scheduled-tasks/',
|
|
159
|
+
],
|
|
160
|
+
// --- red-team reports + bounty (rank-gated Metic+) ---
|
|
161
|
+
security: [
|
|
162
|
+
// Carved into modules/security/ (BV1.R79 / ADR 0093 §1): the red-team /
|
|
163
|
+
// vulnerability-report + bounty FEATURE + the `security` kernel PORT.
|
|
164
|
+
// security-the-PROPERTY (the /security/adr threat-model reader + /security/docs
|
|
165
|
+
// exploit-detail store in src/bongos/routes/security.js) stays KERNEL — it moved
|
|
166
|
+
// to the kernel key (02-module-map §5).
|
|
167
|
+
'modules/security/',
|
|
168
|
+
],
|
|
169
|
+
// --- the two web surfaces ---
|
|
170
|
+
// BV1.R85: hall-UI graduated to modules/hall-ui/ — public-builders/ moved to
|
|
171
|
+
// modules/hall-ui/public/ and is now a loader-discovered web-surface module
|
|
172
|
+
// (contributes.webSurfaces host "builders."). serve-internal keeps the hall's
|
|
173
|
+
// DEDICATED serving block (re-pointed at the module dir), not the generic
|
|
174
|
+
// status-style loop. The me/public/leaderboard reads it renders stay SHARED core
|
|
175
|
+
// in routes/{me,public,builders}.js (the status surface + the off-box mirror read
|
|
176
|
+
// them too).
|
|
177
|
+
'hall-ui': ['modules/hall-ui/'],
|
|
178
|
+
// BV1.R84: status-UI graduated to modules/status-ui/ — public-status/ moved to
|
|
179
|
+
// modules/status-ui/public/ and is now served by the loader web-surface seam
|
|
180
|
+
// (moduleWebSurfaces → serve-internal). Its public read endpoints stay SHARED
|
|
181
|
+
// core in routes/public.js (the hall + the off-box mirror consume them too).
|
|
182
|
+
'status-ui': ['modules/status-ui/'],
|
|
183
|
+
// --- feature modules ---
|
|
184
|
+
// BV1.R49: game graduated to modules/game/ — src/rooms/, src/world/, src/seats.js,
|
|
185
|
+
// src/db.js, migrations/game/, and public/ all moved there. src/preview-server.js
|
|
186
|
+
// stays in src/ as the game-only sandbox entrypoint but is owned by the game module.
|
|
187
|
+
game: [
|
|
188
|
+
'modules/game/', 'src/preview-server.js',
|
|
189
|
+
],
|
|
190
|
+
'art-pipeline': ['modules/art-pipeline/'],
|
|
191
|
+
discord: [
|
|
192
|
+
// The bot, broadcast, link/role seams, channels, and bug-attachments graduated
|
|
193
|
+
// into modules/discord/ (BV1.R47); the outbound webhook lib + post CLI stay
|
|
194
|
+
// core/CLI-side under scripts/discord/.
|
|
195
|
+
'scripts/discord/', 'modules/discord/',
|
|
196
|
+
],
|
|
197
|
+
'dev-box': ['modules/dev-box/', 'devbox-app/'],
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// A glob set is protected iff it overlaps the imported PROTECTED_GLOBS — the one
|
|
201
|
+
// source of truth (permission-path-check.js). Prefix-aware both directions
|
|
202
|
+
// (path-match.touchesOverlap), so e.g. a module owning 'src/bongos/routes/inbox.js'
|
|
203
|
+
// is protected because PROTECTED_GLOBS carries the 'src/bongos/routes/' subtree.
|
|
204
|
+
function isProtected(globs) {
|
|
205
|
+
return touchesOverlap(globs || [], PROTECTED_GLOBS);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// The frozen exported roster: key → { globs:[...], protected:bool } (derived).
|
|
209
|
+
const MODULE_SCOPE_MAP = Object.freeze(
|
|
210
|
+
Object.fromEntries(
|
|
211
|
+
Object.entries(MODULE_GLOBS).map(([key, globs]) => [
|
|
212
|
+
key,
|
|
213
|
+
Object.freeze({ globs: Object.freeze([...globs]), protected: isProtected(globs) }),
|
|
214
|
+
]),
|
|
215
|
+
),
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
function moduleKeys() {
|
|
219
|
+
return Object.keys(MODULE_SCOPE_MAP);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function isModuleKey(key) {
|
|
223
|
+
return Object.prototype.hasOwnProperty.call(MODULE_SCOPE_MAP, key);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// { globs, protected } for one module, or null for an unknown key.
|
|
227
|
+
function scopeForModule(key) {
|
|
228
|
+
return MODULE_SCOPE_MAP[key] || null;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// true / false for a known key; null for an unknown one (caller decides — an
|
|
232
|
+
// unknown module in a goal's scope_modules should fail closed at the route).
|
|
233
|
+
function isProtectedModule(key) {
|
|
234
|
+
const e = MODULE_SCOPE_MAP[key];
|
|
235
|
+
return e ? e.protected : null;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// The protected subset — the modules whose goals require Archon to create.
|
|
239
|
+
function protectedModules() {
|
|
240
|
+
return moduleKeys().filter((k) => MODULE_SCOPE_MAP[k].protected);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Flatten the globs for a set of module keys into one touches[]-style list — what
|
|
244
|
+
// the goal scope-subset check (BV1.R59) tests a task's touches[] against. Unknown
|
|
245
|
+
// keys contribute nothing (the route validates membership separately).
|
|
246
|
+
function globsForModules(keys) {
|
|
247
|
+
const out = [];
|
|
248
|
+
for (const k of keys || []) {
|
|
249
|
+
const e = MODULE_SCOPE_MAP[k];
|
|
250
|
+
if (e) out.push(...e.globs);
|
|
251
|
+
}
|
|
252
|
+
return out;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Does a goal scoped to `keys` include any protected module? (goal-create → Archon)
|
|
256
|
+
function scopeIncludesProtected(keys) {
|
|
257
|
+
return (keys || []).some((k) => isProtectedModule(k) === true);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
module.exports = {
|
|
261
|
+
MODULE_GLOBS,
|
|
262
|
+
MODULE_SCOPE_MAP,
|
|
263
|
+
isProtected,
|
|
264
|
+
moduleKeys,
|
|
265
|
+
isModuleKey,
|
|
266
|
+
scopeForModule,
|
|
267
|
+
isProtectedModule,
|
|
268
|
+
protectedModules,
|
|
269
|
+
globsForModules,
|
|
270
|
+
scopeIncludesProtected,
|
|
271
|
+
};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// GDS session optimizer (P1).
|
|
2
|
+
//
|
|
3
|
+
// Recommends a parallel-safe set of tasks for a given session shape:
|
|
4
|
+
// { builderId, mode, timeBudgetMin, maxParallel }
|
|
5
|
+
//
|
|
6
|
+
// Mode is one of 'active' | 'check-in' | 'autonomous'. The set of tasks
|
|
7
|
+
// that "fit" each mode is derived (not stored) by the tasks_session_fit
|
|
8
|
+
// view in migration 006_pms_v2.sql, computed from automation_tag +
|
|
9
|
+
// manual_degree + blocker presence.
|
|
10
|
+
//
|
|
11
|
+
// Greedy selection:
|
|
12
|
+
// 1. Pull claimable tasks for this builder, joined to tasks_session_fit
|
|
13
|
+
// so we get fits_session_modes[] + credits_per_minute. Filter to
|
|
14
|
+
// tasks whose fits_session_modes contains the requested mode.
|
|
15
|
+
// 2. Sort by credits_per_minute DESC NULLS LAST, then priority ASC,
|
|
16
|
+
// then calibrated minutes ASC.
|
|
17
|
+
// 3. Walk the sorted list; pick a task iff:
|
|
18
|
+
// - chosen.length < maxParallel
|
|
19
|
+
// - calibrated estimate <= timeBudgetMin (falls back to raw
|
|
20
|
+
// est_minutes when calibration is unavailable; NULL passes
|
|
21
|
+
// through — we accept unestimated tasks rather than silently
|
|
22
|
+
// skip them). Calibration: see migration 015.
|
|
23
|
+
// - touches[] is disjoint from every already-chosen task's touches[]
|
|
24
|
+
// 4. Everything not picked becomes the long-tail.
|
|
25
|
+
//
|
|
26
|
+
// We DO NOT enforce sum-of-est_minutes <= timeBudgetMin: this is a
|
|
27
|
+
// PARALLEL set. Each task runs in its own claim/worktree, so the
|
|
28
|
+
// session length is governed by the LONGEST task, not the sum. The
|
|
29
|
+
// per-task est_minutes <= timeBudgetMin guard already enforces that.
|
|
30
|
+
|
|
31
|
+
const { pool } = require('./pool');
|
|
32
|
+
// touches[] cleanup [5/8] (task 880): the same prefix-aware overlap matcher the
|
|
33
|
+
// claim guard uses, so the planner's "parallel-safe set" agrees with what
|
|
34
|
+
// claimTask / claimTasksBatch will actually allow.
|
|
35
|
+
const { touchesOverlap } = require('./path-match');
|
|
36
|
+
|
|
37
|
+
const VALID_MODES = ['active', 'check-in', 'autonomous'];
|
|
38
|
+
const DEFAULT_MAX_PARALLEL = 3;
|
|
39
|
+
|
|
40
|
+
async function optimizeSession({ builderId, mode, timeBudgetMin, maxParallel }) {
|
|
41
|
+
if (!VALID_MODES.includes(mode)) {
|
|
42
|
+
throw { code: 'BAD_MODE', validModes: VALID_MODES };
|
|
43
|
+
}
|
|
44
|
+
if (!Number.isFinite(timeBudgetMin) || timeBudgetMin <= 0) {
|
|
45
|
+
throw { code: 'BAD_TIME_BUDGET' };
|
|
46
|
+
}
|
|
47
|
+
const cap = Number.isFinite(maxParallel) && maxParallel > 0
|
|
48
|
+
? Math.floor(maxParallel)
|
|
49
|
+
: DEFAULT_MAX_PARALLEL;
|
|
50
|
+
|
|
51
|
+
// Join claimable_tasks (already enforces status='ready', not blocked,
|
|
52
|
+
// touches-disjoint vs other builders' active claims, smoke-filter) with
|
|
53
|
+
// tasks_session_fit (derived fits_session_modes[] + credits_per_minute).
|
|
54
|
+
// Also exclude tasks this builder already has an active claim on, mirroring
|
|
55
|
+
// listClaimableTasks in db.js.
|
|
56
|
+
const { rows } = await pool.query(
|
|
57
|
+
`SELECT ct.*, sf.fits_session_modes, sf.credits_per_minute
|
|
58
|
+
FROM claimable_tasks ct
|
|
59
|
+
JOIN tasks_session_fit sf ON sf.id = ct.id
|
|
60
|
+
WHERE $1 = ANY(sf.fits_session_modes)
|
|
61
|
+
AND NOT EXISTS (
|
|
62
|
+
SELECT 1 FROM claims c
|
|
63
|
+
WHERE c.task_id = ct.id
|
|
64
|
+
AND c.builder_id = $2
|
|
65
|
+
AND c.released_at IS NULL
|
|
66
|
+
)
|
|
67
|
+
ORDER BY sf.credits_per_minute DESC NULLS LAST,
|
|
68
|
+
ct.priority ASC NULLS LAST,
|
|
69
|
+
COALESCE(ct.est_minutes_calibrated, ct.est_minutes) ASC NULLS LAST,
|
|
70
|
+
ct.id ASC`,
|
|
71
|
+
[mode, builderId]
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const chosen = [];
|
|
75
|
+
const longTail = [];
|
|
76
|
+
const chosenTouches = []; // accumulated touches[] of everything already chosen
|
|
77
|
+
|
|
78
|
+
for (const task of rows) {
|
|
79
|
+
if (chosen.length >= cap) {
|
|
80
|
+
longTail.push(task);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const effectiveMinutes = task.est_minutes_calibrated ?? task.est_minutes;
|
|
84
|
+
if (effectiveMinutes != null && effectiveMinutes > timeBudgetMin) {
|
|
85
|
+
longTail.push(task);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const touches = Array.isArray(task.touches) ? task.touches : [];
|
|
89
|
+
// Prefix-aware overlap (was JS Set-equality, which missed dir-prefix
|
|
90
|
+
// adjacency) so the recommended set matches the claim-time guard.
|
|
91
|
+
if (touchesOverlap(touches, chosenTouches)) {
|
|
92
|
+
longTail.push(task);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
chosen.push(task);
|
|
96
|
+
for (const t of touches) chosenTouches.push(t);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// CLI (scripts/gds/session.js printPlan) expects this exact shape, matching
|
|
100
|
+
// the local-fallback contract: { recommended, long_tail, rationale_for,
|
|
101
|
+
// time_used_min, time_budget_min }. The local fallback was written first
|
|
102
|
+
// and is the canonical contract — this endpoint was diverging in field
|
|
103
|
+
// names + per-task rationale and crashing the CLI on every 200 response
|
|
104
|
+
// (idea #12 → task #176).
|
|
105
|
+
const rationale_for = {};
|
|
106
|
+
for (const t of chosen) {
|
|
107
|
+
const m = (t.est_minutes_calibrated ?? t.est_minutes) || 60;
|
|
108
|
+
const cpm = t.credits_per_minute != null ? Number(t.credits_per_minute) : ((t.credits_reward || 0) / m);
|
|
109
|
+
const mFmt = m < 60 ? `${m}min` : `${(m / 60).toFixed(1)}h`;
|
|
110
|
+
rationale_for[t.id] = `${(cpm * 60).toFixed(1)}c/h · ${mFmt} · P${t.priority ?? '?'}`;
|
|
111
|
+
}
|
|
112
|
+
const time_used_min = chosen.reduce(
|
|
113
|
+
(s, t) => s + ((t.est_minutes_calibrated ?? t.est_minutes) || 0),
|
|
114
|
+
0
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
// `recommended` is a touches-DISJOINT set (the prefix-aware overlap filter
|
|
119
|
+
// above guarantees no two chosen tasks share a path). System 3 (ADR 0079)
|
|
120
|
+
// relies on that: the overnight builder, when armed, fans these workers from
|
|
121
|
+
// ONE supervisor that loads orientation once — disjointness is what makes the
|
|
122
|
+
// concurrent fan claim-safe and merge-safe (the merge leg stays serialized).
|
|
123
|
+
recommended: chosen,
|
|
124
|
+
long_tail: longTail,
|
|
125
|
+
rationale_for,
|
|
126
|
+
time_used_min,
|
|
127
|
+
time_budget_min: timeBudgetMin,
|
|
128
|
+
// rationale stays as a top-level human-readable summary for any non-CLI
|
|
129
|
+
// consumer (web UI, future dashboards). CLI ignores it; safe to keep.
|
|
130
|
+
rationale: buildRationale({
|
|
131
|
+
chosen,
|
|
132
|
+
longTail,
|
|
133
|
+
mode,
|
|
134
|
+
timeBudgetMin,
|
|
135
|
+
cap,
|
|
136
|
+
}),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function buildRationale({ chosen, longTail, mode, timeBudgetMin, cap }) {
|
|
141
|
+
if (chosen.length === 0) {
|
|
142
|
+
if (longTail.length === 0) {
|
|
143
|
+
return `No claimable tasks fit mode '${mode}' for this builder right now.`;
|
|
144
|
+
}
|
|
145
|
+
return `No tasks within ${timeBudgetMin}min budget for mode '${mode}'; ${longTail.length} candidate(s) all exceed the budget or conflict.`;
|
|
146
|
+
}
|
|
147
|
+
const longest = chosen.reduce(
|
|
148
|
+
(acc, t) => {
|
|
149
|
+
const m = t.est_minutes_calibrated ?? t.est_minutes;
|
|
150
|
+
return m != null && m > acc ? m : acc;
|
|
151
|
+
},
|
|
152
|
+
0
|
|
153
|
+
);
|
|
154
|
+
const sumCredits = chosen.reduce((acc, t) => acc + (t.credits_reward || 0), 0);
|
|
155
|
+
const cap_phrase = chosen.length === cap ? ` (capped at max_parallel=${cap})` : '';
|
|
156
|
+
const longest_phrase = longest > 0
|
|
157
|
+
? `; longest task is ${longest}min within ${timeBudgetMin}min budget`
|
|
158
|
+
: '';
|
|
159
|
+
return `Selected ${chosen.length} task(s)${cap_phrase}: highest credits-per-minute fitting '${mode}' mode with disjoint touches[]${longest_phrase}. Total reward: ${sumCredits} credits. Long-tail: ${longTail.length} task(s) deferred.`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
module.exports = {
|
|
163
|
+
optimizeSession,
|
|
164
|
+
VALID_MODES,
|
|
165
|
+
DEFAULT_MAX_PARALLEL,
|
|
166
|
+
};
|