@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,208 @@
|
|
|
1
|
+
// src/bongos/routes/access-requests.js — onboarding cold-start (2026-05-30).
|
|
2
|
+
//
|
|
3
|
+
// The hall is gated: a brand-new person can't enter until an Archon admits
|
|
4
|
+
// them. Admission is the ONLY gate — newcomers build on hosted dev boxes, so
|
|
5
|
+
// they need no GitHub repo access / collaborator invite (2026-06-07). 'invited'
|
|
6
|
+
// just means "Archon-approved for the hall"; the web sign-in (auth.js) checks
|
|
7
|
+
// exactly that one flag. This router is how they ask and how the Archon
|
|
8
|
+
// answers:
|
|
9
|
+
//
|
|
10
|
+
// POST /api/bongos/access-requests PUBLIC (the one unauthenticated GDS
|
|
11
|
+
// write) — a stranger submits their
|
|
12
|
+
// GitHub username; a pending row lands
|
|
13
|
+
// in the queue.
|
|
14
|
+
// GET /api/bongos/access-requests Archon-only — the pending queue (and
|
|
15
|
+
// ?status=invited|dismissed history).
|
|
16
|
+
// PATCH /api/bongos/access-requests/:id Archon-only — resolve a request:
|
|
17
|
+
// { status: 'invited' | 'dismissed' }.
|
|
18
|
+
//
|
|
19
|
+
// The global IP rate-limiter (mounted in routes.js before every router) guards
|
|
20
|
+
// the public POST against spam. A partial unique index on lower(github_login)
|
|
21
|
+
// stops one username piling up duplicate open requests.
|
|
22
|
+
|
|
23
|
+
const express = require('express');
|
|
24
|
+
// Carved into modules/onboarding/ (BV1.R81 / ADR 0093 §1). The auth gates, the
|
|
25
|
+
// shared pool, and the route validators reach the published doorway (the only
|
|
26
|
+
// core file a module may require, ADR 0083); approval-broadcast travels WITH this
|
|
27
|
+
// admission route (its sole consumer) and is an intra-module require.
|
|
28
|
+
const api = require('../../../src/module-api');
|
|
29
|
+
const auth = { requireBuilder: api.requireBuilder, requireRank: api.requireRank };
|
|
30
|
+
const { pool } = api;
|
|
31
|
+
const { validateOrRespond, parseId } = api;
|
|
32
|
+
const approvalBroadcast = require('../approval-broadcast');
|
|
33
|
+
|
|
34
|
+
// GitHub usernames: 1–39 chars, alphanumeric or single hyphens, no leading/
|
|
35
|
+
// trailing hyphen. We accept a leading '@' and strip it (people paste "@name").
|
|
36
|
+
const GITHUB_LOGIN_RE = /^[a-zA-Z0-9](?:[a-zA-Z0-9]|-(?=[a-zA-Z0-9])){0,38}$/;
|
|
37
|
+
|
|
38
|
+
function normalizeLogin(raw) {
|
|
39
|
+
return String(raw || '').trim().replace(/^@/, '');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = function buildAccessRequestsRouter() {
|
|
43
|
+
const router = express.Router();
|
|
44
|
+
|
|
45
|
+
// POST /access-requests — PUBLIC. A would-be builder asks to be admitted.
|
|
46
|
+
// rank: public — the requester is by definition outside the system (no
|
|
47
|
+
// builder row yet); this is the one public write on the GDS.
|
|
48
|
+
router.post('/access-requests', async (req, res) => {
|
|
49
|
+
if (validateOrRespond(req, res, {
|
|
50
|
+
github_login: { required: true, type: 'string', minLength: 1, maxLength: 60 },
|
|
51
|
+
display_name: { type: 'string', maxLength: 100 },
|
|
52
|
+
note: { type: 'string', maxLength: 500 },
|
|
53
|
+
})) return;
|
|
54
|
+
|
|
55
|
+
const login = normalizeLogin(req.body.github_login);
|
|
56
|
+
if (!GITHUB_LOGIN_RE.test(login)) {
|
|
57
|
+
return res.fail('bad_github_login', { status: 400, message: 'That does not look like a GitHub username.' });
|
|
58
|
+
}
|
|
59
|
+
const displayName = (req.body.display_name || '').trim() || null;
|
|
60
|
+
const note = (req.body.note || '').trim() || null;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
// Already a builder? They have an account — point them at sign-in instead
|
|
64
|
+
// of opening a redundant request. (2026-05-30)
|
|
65
|
+
const member = await pool.query(
|
|
66
|
+
`SELECT 1 FROM builders WHERE lower(github_login) = lower($1) LIMIT 1`,
|
|
67
|
+
[login]
|
|
68
|
+
);
|
|
69
|
+
if (member.rows.length > 0) {
|
|
70
|
+
return res.fail('already_member', { status: 409, message: 'You already have an account — just sign in with GitHub.' });
|
|
71
|
+
}
|
|
72
|
+
// Already approved (invited) but not yet signed in? No new request needed.
|
|
73
|
+
const invited = await pool.query(
|
|
74
|
+
`SELECT 1 FROM access_requests
|
|
75
|
+
WHERE lower(github_login) = lower($1) AND status = 'invited' LIMIT 1`,
|
|
76
|
+
[login]
|
|
77
|
+
);
|
|
78
|
+
if (invited.rows.length > 0) {
|
|
79
|
+
return res.fail('already_approved', { status: 409, message: "You're already approved — sign in with GitHub to enter." });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const { rows } = await pool.query(
|
|
83
|
+
`INSERT INTO access_requests (github_login, display_name, note)
|
|
84
|
+
VALUES ($1, $2, $3)
|
|
85
|
+
RETURNING id, github_login, status, created_at`,
|
|
86
|
+
[login, displayName, note]
|
|
87
|
+
);
|
|
88
|
+
// Post the request to #member-approvals so an Archon can 👍/👎 it from
|
|
89
|
+
// Discord (task 1100). Fire-and-forget + best-effort — never blocks or
|
|
90
|
+
// fails the public submit (the hall queue is the source of truth either
|
|
91
|
+
// way). display_name/note aren't in the RETURNING set, so pass them along.
|
|
92
|
+
approvalBroadcast
|
|
93
|
+
.postMemberApprovalRequest({ ...rows[0], display_name: displayName, note })
|
|
94
|
+
.catch(() => {});
|
|
95
|
+
return res.status(201).json({ ok: true, request: rows[0] });
|
|
96
|
+
} catch (err) {
|
|
97
|
+
// Partial unique index → there's already an open request for this login.
|
|
98
|
+
// Treat as success-ish: the Archon already has them in the queue.
|
|
99
|
+
if (err.code === '23505') {
|
|
100
|
+
return res.status(200).json({ ok: true, already_pending: true });
|
|
101
|
+
}
|
|
102
|
+
console.error('[gds] POST /access-requests', err);
|
|
103
|
+
return res.fail('access_request_failed', { status: 500, message: 'internal error' });
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// GET /access-requests/status?github_login=X — PUBLIC. The `bongos login` CLI
|
|
108
|
+
// polls this after filing a request: the device flow's not_approved is TERMINAL
|
|
109
|
+
// (the device_code is spent), so the CLI can't re-poll the flow — it polls this
|
|
110
|
+
// instead, then restarts sign-in once admitted. Exposes nothing the public POST
|
|
111
|
+
// above doesn't already reveal through its 409s (already_member / already_approved).
|
|
112
|
+
// status ∈ member | invited | pending | dismissed | none; admitted = member||invited.
|
|
113
|
+
// rank: public — a would-be builder is by definition outside the system.
|
|
114
|
+
// Declared BEFORE `GET /access-requests` so the literal `/status` path is matched
|
|
115
|
+
// as its own route (not swallowed as a query on the list route).
|
|
116
|
+
router.get('/access-requests/status', async (req, res) => {
|
|
117
|
+
const login = normalizeLogin(req.query.github_login);
|
|
118
|
+
if (!GITHUB_LOGIN_RE.test(login)) {
|
|
119
|
+
return res.fail('bad_github_login', { status: 400, message: 'That does not look like a GitHub username.' });
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
const member = await pool.query(
|
|
123
|
+
`SELECT 1 FROM builders WHERE lower(github_login) = lower($1) LIMIT 1`,
|
|
124
|
+
[login]
|
|
125
|
+
);
|
|
126
|
+
if (member.rows.length > 0) {
|
|
127
|
+
return res.json({ github_login: login, status: 'member', admitted: true });
|
|
128
|
+
}
|
|
129
|
+
// Prefer an 'invited' row if one exists, else the most recent request.
|
|
130
|
+
const ar = await pool.query(
|
|
131
|
+
`SELECT status FROM access_requests
|
|
132
|
+
WHERE lower(github_login) = lower($1)
|
|
133
|
+
ORDER BY (status = 'invited') DESC, created_at DESC
|
|
134
|
+
LIMIT 1`,
|
|
135
|
+
[login]
|
|
136
|
+
);
|
|
137
|
+
const status = ar.rows.length > 0 ? ar.rows[0].status : 'none';
|
|
138
|
+
return res.json({ github_login: login, status, admitted: status === 'invited' });
|
|
139
|
+
} catch (err) {
|
|
140
|
+
console.error('[gds] GET /access-requests/status', err);
|
|
141
|
+
return res.fail('status_failed', { status: 500, message: 'internal error' });
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// GET /access-requests?status=pending — Archon queue. Defaults to pending;
|
|
146
|
+
// pass ?status=invited|dismissed for the resolved history.
|
|
147
|
+
// rank: archon — the queue exposes would-be builders' usernames.
|
|
148
|
+
router.get('/access-requests', auth.requireBuilder, auth.requireRank('archon'), async (req, res) => {
|
|
149
|
+
const status = req.query.status || 'pending';
|
|
150
|
+
if (!['pending', 'invited', 'dismissed'].includes(status)) {
|
|
151
|
+
return res.fail('bad_status', 400);
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
const { rows } = await pool.query(
|
|
155
|
+
`SELECT ar.id, ar.github_login, ar.display_name, ar.note, ar.status,
|
|
156
|
+
ar.created_at, ar.resolved_at,
|
|
157
|
+
rb.github_login AS resolved_by_login
|
|
158
|
+
FROM access_requests ar
|
|
159
|
+
LEFT JOIN builders rb ON rb.id = ar.resolved_by_builder_id
|
|
160
|
+
WHERE ar.status = $1
|
|
161
|
+
ORDER BY ar.created_at DESC
|
|
162
|
+
LIMIT 200`,
|
|
163
|
+
[status]
|
|
164
|
+
);
|
|
165
|
+
res.json({ requests: rows });
|
|
166
|
+
} catch (err) {
|
|
167
|
+
console.error('[gds] GET /access-requests', err);
|
|
168
|
+
res.fail('list_failed', { status: 500, message: 'internal error' });
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// PATCH /access-requests/:id — Archon resolves a request.
|
|
173
|
+
// body: { status: 'invited' | 'dismissed' }. 'invited' = admitted to the hall
|
|
174
|
+
// (the only sign-in gate — no repo access needed); 'dismissed' = declined /
|
|
175
|
+
// spam / dup. The row stays as the audit trail either way.
|
|
176
|
+
// rank: archon — same gate as the rest of the roster management surface.
|
|
177
|
+
router.patch('/access-requests/:id', auth.requireBuilder, auth.requireRank('archon'), async (req, res) => {
|
|
178
|
+
const id = parseId(req, res, { code: 'bad_request_id' });
|
|
179
|
+
if (id === null) return;
|
|
180
|
+
if (validateOrRespond(req, res, {
|
|
181
|
+
status: { required: true, type: 'string' },
|
|
182
|
+
})) return;
|
|
183
|
+
const next = req.body.status;
|
|
184
|
+
if (!['invited', 'dismissed'].includes(next)) {
|
|
185
|
+
return res.fail('bad_status', { status: 400, message: "status must be 'invited' or 'dismissed'." });
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
const { rows } = await pool.query(
|
|
189
|
+
`UPDATE access_requests
|
|
190
|
+
SET status = $1,
|
|
191
|
+
resolved_by_builder_id = $2,
|
|
192
|
+
resolved_at = now()
|
|
193
|
+
WHERE id = $3 AND status = 'pending'
|
|
194
|
+
RETURNING id, github_login, status, resolved_at`,
|
|
195
|
+
[next, req.builder.id, id]
|
|
196
|
+
);
|
|
197
|
+
if (rows.length === 0) {
|
|
198
|
+
return res.fail('not_pending', { status: 409, message: 'That request is gone or already resolved.' });
|
|
199
|
+
}
|
|
200
|
+
res.json({ ok: true, request: rows[0] });
|
|
201
|
+
} catch (err) {
|
|
202
|
+
console.error('[gds] PATCH /access-requests/:id', err);
|
|
203
|
+
res.fail('resolve_failed', { status: 500, message: 'internal error' });
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
return router;
|
|
208
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// modules/onboarding/routes/onboarding.js — the onboarding module's route
|
|
4
|
+
// factory (BV1.R81 / ADR 0093 §1).
|
|
5
|
+
//
|
|
6
|
+
// Two jobs, both run by the loader at boot (and again whenever a test rebuilds
|
|
7
|
+
// the GDS router):
|
|
8
|
+
//
|
|
9
|
+
// 1. REGISTER the `onboarding` kernel PORT (below). The CORE consumers — the
|
|
10
|
+
// lifecycle (db.js claim/ship), the auth callbacks, and the me/builders
|
|
11
|
+
// profile readers + the tasks/claims chore-restock path — resolve it instead
|
|
12
|
+
// of importing this module (the boundary rule: core never requires a
|
|
13
|
+
// module). Pattern mirrors modules/economy/routes/reward.js +
|
|
14
|
+
// modules/builder-settings/routes/settings.js — registered from the route
|
|
15
|
+
// factory (the one boot hook that runs both live AND under a test router
|
|
16
|
+
// rebuild), hasProvider-guarded so re-instantiation never trips the
|
|
17
|
+
// single-provider guard.
|
|
18
|
+
//
|
|
19
|
+
// 2. MOUNT the ADMISSION routes (the access-request cold-start: the one public
|
|
20
|
+
// GDS write + the two Archon-only resolve endpoints). They moved here
|
|
21
|
+
// verbatim from core src/bongos/routes/access-requests.js — they keep their
|
|
22
|
+
// exact /access-requests paths (the loader mounts this router on the same
|
|
23
|
+
// /api/bongos router, BEFORE the public catch-all), so the API is byte-
|
|
24
|
+
// identical; only the require() paths changed (auth/pool/validators reach
|
|
25
|
+
// the doorway; approval-broadcast travels with the route as an intra-module
|
|
26
|
+
// require).
|
|
27
|
+
//
|
|
28
|
+
// The onboarding STATE MACHINE has no /me/* or /builders/* routes of its own —
|
|
29
|
+
// those aggregator endpoints stay in core (routes/me.js, routes/builders.js) and
|
|
30
|
+
// resolve the port for their onboarding slices (the GET /me facade precedent,
|
|
31
|
+
// 02-module-map §2). So the only HTTP surface this module owns is admission.
|
|
32
|
+
|
|
33
|
+
const express = require('express');
|
|
34
|
+
const api = require('../../../src/module-api');
|
|
35
|
+
const onboardingPort = require('../port');
|
|
36
|
+
const buildAccessRequestsRouter = require('./access-requests');
|
|
37
|
+
|
|
38
|
+
// Register the `onboarding` kernel PORT. See the header + port.js for the full
|
|
39
|
+
// consumer list and the graceful-degradation contract.
|
|
40
|
+
function registerSeams() {
|
|
41
|
+
if (!api.hasProvider('onboarding')) {
|
|
42
|
+
api.registerProvider('onboarding', onboardingPort);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = function buildOnboardingRouter() {
|
|
47
|
+
registerSeams();
|
|
48
|
+
const router = express.Router();
|
|
49
|
+
// The admission cold-start endpoints (POST /access-requests public + the two
|
|
50
|
+
// Archon-only resolve routes). Mounted on this same /api/bongos router by the
|
|
51
|
+
// loader, before the public catch-all — byte-identical paths.
|
|
52
|
+
router.use(buildAccessRequestsRouter());
|
|
53
|
+
return router;
|
|
54
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# `security` module — red-team reports + bounty + the `security` kernel port
|
|
2
|
+
|
|
3
|
+
> The **fifth CORE-domain** carved into a module (BV1.R79, [ADR 0093](../../docs/adr/<redacted>.md) §1) — after memory (R72), grading (R73), economy (R77), and ideas (R78). This is **<redacted>**, not <redacted> ([02-module-map §5](../../docs/design/modular-architecture/02-module-map.md)): the optional, rank-gated red-team-reports + bounty surface. A clean slice — its SQL already lived in a dedicated `security.js` (not the `db.js` monolith), so the carve is a git-move + a route split + a doorway re-point, OTB byte-identical. `default: true` in `module.json` — every instance can take red-team reports.
|
|
4
|
+
|
|
5
|
+
Owns the **red-team / vulnerability-report** lifecycle (file → adjudicate → pay) and the **bounty payout table**: the `/builder-redteam` skill POSTs a report (Metic+), the Archon dashboard reads + adjudicates it (confirm / dispute / fix / link-fix), and the env-aware per-severity drachmae schedule (the bounty table) is the single source of truth for "how much for a confirmed report."
|
|
6
|
+
|
|
7
|
+
## The boundary (the one rule)
|
|
8
|
+
|
|
9
|
+
This module reaches core **only** through the published doorway [`../../src/module-api.js`](../../src/module-api.js) (`coreVersion ^1.8.0`). It must **never** `require()` a core internal directly, and never another module. Core, in turn, must never `require()` a file in here — it reaches the bounty schedule only through the `security` port (below). Both directions are enforced by the BV1.R44/R45 fitness checks.
|
|
10
|
+
|
|
11
|
+
## <redacted> stays KERNEL (the headline boundary call)
|
|
12
|
+
|
|
13
|
+
[02-module-map §5](../../docs/design/modular-architecture/02-module-map.md) splits "security" in two, and only one half is here:
|
|
14
|
+
|
|
15
|
+
- **PROPERTY → kernel (NOT moved):** the authz / trust-boundary machinery — `permission-path-check.js`, `route-rank-check.js`, `requireRank`/`requireBuilder` (`auth.js`). Imported everywhere, enforced by composition + fitness functions, never "called." Untouched by this carve.
|
|
16
|
+
- **PROPERTY → kernel (NOT moved, the subtle part):** the **threat-model + engagement-doc plane** also stayed in core `src/bongos/routes/security.js`: `GET /security/adr` (reads the real ADR 0020 threat model off the droplet, Metic+) and `GET/POST /security/docs` (the Archon-only exploit-detail engagement-report store, backed by the core `db.js` `security_docs` queries). These document **defenses + exploits** — security-the-property's operational surface, not the bounty feature. They keep their `EXPECTED_RANKS` pins in `route-rank-check.js`.
|
|
17
|
+
- **FEATURE → this module:** red-team / vulnerability **reports** + **bounty** (`/security/reports*`) and the payout table. Self-contained, optional, rank-gated.
|
|
18
|
+
|
|
19
|
+
The core `src/bongos/routes/security.js` therefore did **not** disappear — it was *split*: the report/bounty routes moved here; the adr/docs (property) routes stayed.
|
|
20
|
+
|
|
21
|
+
## The `security` kernel PORT
|
|
22
|
+
|
|
23
|
+
- **Provides — port `security`** → `{ bountyTableDetailed, bountyTable }`. Registered in `routes/reports.js`'s factory (the loader runs it at boot, and again whenever a test rebuilds the GDS router — `hasProvider`-guarded so re-instantiation never trips the single-provider guard). Mirrors `modules/economy/routes/reward.js`.
|
|
24
|
+
- **Why:** the **one** core consumer of the security feature is `src/bongos/routes/public.js`'s `GET /public/bounty-table` (the public payout schedule the hall renders). Core can't `require()` a module, so it resolves `seams.resolveOptional('security').bountyTableDetailed()` — the economy `reward`-port precedent for a core read route reaching module data.
|
|
25
|
+
|
|
26
|
+
## Files
|
|
27
|
+
|
|
28
|
+
| File | What |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `security.js` | the bounty payout table (`bountyTable`/`bountyTableDetailed`, env-overridable per severity via `GDS_BOUNTY_*`) + the `vulnerability_reports` domain: `createVulnerabilityReport` (the `/builder-redteam` writer), `listVulnerabilityReports({scope})`, and the Archon adjudication transitions (`confirm`/`dispute`/`markFixed`/`linkFix`). Reaches the shared pool through the doorway. |
|
|
31
|
+
| `routes/reports.js` | `POST /security/reports` (Metic+ file), `GET /security/reports` (Archon list), `POST /security/reports/:id/{confirm,dispute,fix,link-fix}` (Archon adjudicate). Its factory **registers the `security` port**. |
|
|
32
|
+
|
|
33
|
+
## NOT in this module (deliberately left in core)
|
|
34
|
+
|
|
35
|
+
- **The threat-model + engagement-doc routes** — `src/bongos/routes/security.js` keeps `GET /security/adr` + `GET/POST /security/docs` (security-the-property; see the boundary call above). They use the core `db.js` `security_docs` queries and `auth`/`_helpers` directly — core code, not this module.
|
|
36
|
+
- **The `/builder-redteam` skill** — `.claude/skills/builder-redteam/` travels with the feature but stays under `.claude/skills/` (it just POSTs to `/api/gds/security/reports`, which this module now mounts).
|
|
37
|
+
|
|
38
|
+
## Tables
|
|
39
|
+
|
|
40
|
+
None owned. `vulnerability_reports` (migration 030) and `security_docs` (the property-side store) were created before the module system and stay in core `migrations/` (the `schema_migrations` stem-key makes a later relocation a no-op). This module owns the *report/bounty queries*; any **new** security-feature migration belongs in `modules/security/migrations/` namespaced `security_*` (the additive rule).
|
|
41
|
+
|
|
42
|
+
## Tests
|
|
43
|
+
|
|
44
|
+
`tests/security_reports.mjs` exercises the report/bounty domain (the `security.js` helpers + the bounty table). The route-rank fitness check (`tests/module_route_rank.mjs`) asserts every write route in `routes/reports.js` is rank-gated. The doorway/boundary checks (`tests/fitness.mjs`, `tests/module_loader.mjs`) discover `security` as a module. See [ADR 0093](../../docs/adr/<redacted>.md).
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"key": "security",
|
|
3
|
+
"title": "Security (red-team · bounty)",
|
|
4
|
+
"description": "The red-team / vulnerability-report intake and the bounty payout system (rank-gated Metic+): the /builder-redteam skill files a report, the Archon dashboard adjudicates (confirm/dispute/fix/link-fix), and the env-aware bounty table sets the per-severity drachmae payout. A core-domain module carved out of the GDS core in BV1.R79 (ADR 0093 §1; 02-module-map §5 — security-the-FEATURE, NOT security-the-property, which stays kernel). default-on because every instance can take red-team reports. Registers the `security` kernel PORT the core /public/bounty-table resolves for the payout schedule.",
|
|
5
|
+
"coreVersion": "^1.8.0",
|
|
6
|
+
"default": true,
|
|
7
|
+
"contributes": { "routes": ["reports"] },
|
|
8
|
+
"provides": ["security"],
|
|
9
|
+
"consumes": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
// modules/security/routes/reports.js — the red-team / vulnerability-report +
|
|
2
|
+
// bounty intake & adjudication surface (BV1.R79 / ADR 0093 §1).
|
|
3
|
+
//
|
|
4
|
+
// Carved out of the core src/bongos/routes/security.js (V3.R63-R66 / #282-285): the
|
|
5
|
+
// FEATURE half — file a report (Metic+), the Archon watch + adjudication view, and
|
|
6
|
+
// the bounty payout table. security-the-PROPERTY (the /security/adr threat-model
|
|
7
|
+
// reader + /security/docs exploit-detail store) STAYS in core (02-module-map §5).
|
|
8
|
+
// OTB byte-identical — only the require() paths changed: auth gates + request
|
|
9
|
+
// validators reach through the published doorway; the security domain is an
|
|
10
|
+
// intra-module require (a module never requires a core internal).
|
|
11
|
+
//
|
|
12
|
+
// This factory also REGISTERS the `security` kernel PORT (below): the bounty
|
|
13
|
+
// payout table the core public route resolves instead of importing the module.
|
|
14
|
+
|
|
15
|
+
const express = require('express');
|
|
16
|
+
const api = require('../../../src/module-api');
|
|
17
|
+
const security = require('../security');
|
|
18
|
+
const { validateOrRespond, LIMITS, parseId } = api;
|
|
19
|
+
|
|
20
|
+
// Register the `security` kernel PORT (BV1.R79 / ADR 0093 §1). The ONLY core
|
|
21
|
+
// consumer of the security feature is routes/public.js's /public/bounty-table,
|
|
22
|
+
// which renders the env-aware payout schedule — it resolves this port instead of
|
|
23
|
+
// importing the module (the boundary rule: core never requires a module). Pattern
|
|
24
|
+
// mirrors modules/economy/routes/reward.js — registered from the route factory (the
|
|
25
|
+
// one boot hook that runs both live AND when a test rebuilds the GDS router),
|
|
26
|
+
// hasProvider-guarded so re-instantiation never trips the single-provider guard.
|
|
27
|
+
// The seam functions are flat doorway exports (api.hasProvider/registerProvider).
|
|
28
|
+
function registerSeams() {
|
|
29
|
+
if (!api.hasProvider('security')) {
|
|
30
|
+
api.registerProvider('security', {
|
|
31
|
+
// pure, DB-free, env-derived payout schedule the public bounty-table feeds
|
|
32
|
+
bountyTableDetailed: (...a) => security.bountyTableDetailed(...a),
|
|
33
|
+
bountyTable: (...a) => security.bountyTable(...a),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = function buildSecurityReportsRouter() {
|
|
39
|
+
registerSeams();
|
|
40
|
+
const router = express.Router();
|
|
41
|
+
|
|
42
|
+
// -----------------------------------------------------------------------
|
|
43
|
+
// Vulnerability reports — file (Metic+) + Archon adjudication (V3.R64/R66).
|
|
44
|
+
//
|
|
45
|
+
// The Archon-only watch surface in the /builders hall reads through these
|
|
46
|
+
// endpoints. The "own" path for non-Archons (a builder reading their own
|
|
47
|
+
// reports) is a future surface — for now everything read here is Archon, since
|
|
48
|
+
// the only consumer that exists is the Archon dashboard view.
|
|
49
|
+
// -----------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
// POST /api/bongos/security/reports — file a new vulnerability report.
|
|
52
|
+
//
|
|
53
|
+
// V3.R64 (#283). Used by the /builder-redteam skill. Metic+ only — Xenos
|
|
54
|
+
// can't open the bounty surface (the rank gate keeps the noise-floor sane;
|
|
55
|
+
// a Xenos who finds a real flaw can flag it through normal channels).
|
|
56
|
+
//
|
|
57
|
+
// Body: { target, severity, title, description?, repro_steps_md? }
|
|
58
|
+
// Returns 201 + the inserted row (status='open' by default; the Archon view
|
|
59
|
+
// picks it up immediately).
|
|
60
|
+
//
|
|
61
|
+
// rank: metic+archon — bounty intake; Xenos kept out by design (V3.R63).
|
|
62
|
+
router.post(
|
|
63
|
+
'/security/reports',
|
|
64
|
+
api.requireBuilder,
|
|
65
|
+
api.requireRank('metic', 'archon'),
|
|
66
|
+
async (req, res) => {
|
|
67
|
+
if (validateOrRespond(req, res, {
|
|
68
|
+
target: { required: true, type: 'string', maxLength: LIMITS.TITLE, minLength: 1 },
|
|
69
|
+
severity: { required: true, type: 'string', maxLength: 32 },
|
|
70
|
+
title: { required: true, type: 'string', maxLength: LIMITS.TITLE, minLength: 1 },
|
|
71
|
+
description: { type: 'string', maxLength: LIMITS.DESCRIPTION },
|
|
72
|
+
repro_steps_md: { type: 'string', maxLength: LIMITS.DESCRIPTION },
|
|
73
|
+
})) return;
|
|
74
|
+
const { target, severity, title, description, repro_steps_md: reproStepsMd } = req.body || {};
|
|
75
|
+
try {
|
|
76
|
+
const row = await security.createVulnerabilityReport({
|
|
77
|
+
reporterBuilderId: req.builder.id,
|
|
78
|
+
target,
|
|
79
|
+
severity,
|
|
80
|
+
title,
|
|
81
|
+
description: description ?? null,
|
|
82
|
+
reproStepsMd: reproStepsMd ?? null,
|
|
83
|
+
});
|
|
84
|
+
res.status(201).json({ ok: true, report: row, bounty_table: security.bountyTable() });
|
|
85
|
+
} catch (err) {
|
|
86
|
+
if (err && err.code === 'INVALID_SEVERITY') {
|
|
87
|
+
return res.fail('invalid_severity', 400, { allowed: err.allowed });
|
|
88
|
+
}
|
|
89
|
+
console.error('[gds] POST /security/reports', err);
|
|
90
|
+
res.fail('create_failed', { status: 500, message: 'internal error' });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
// GET /api/bongos/security/reports?status=<status>
|
|
96
|
+
//
|
|
97
|
+
// Archon-only, newest-first. The Archon dashboard view fetches this on
|
|
98
|
+
// load + after each adjudication action. ?status= narrows to one
|
|
99
|
+
// lifecycle bucket (open / repro_attempted / confirmed / disputed /
|
|
100
|
+
// fixed / wontfix); omitted = all.
|
|
101
|
+
//
|
|
102
|
+
// rank: archon — adjudication surface; reading every builder's reports.
|
|
103
|
+
router.get(
|
|
104
|
+
'/security/reports',
|
|
105
|
+
api.requireBuilder,
|
|
106
|
+
api.requireRank('archon'),
|
|
107
|
+
async (req, res) => {
|
|
108
|
+
const status = req.query.status ? String(req.query.status) : null;
|
|
109
|
+
if (status && !security.VULN_STATUSES.includes(status)) {
|
|
110
|
+
return res.fail('bad_status', 400, { allowed: security.VULN_STATUSES });
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const reports = await security.listVulnerabilityReports({ scope: 'all', status });
|
|
114
|
+
// The bounty table comes along so the UI can render "would pay X
|
|
115
|
+
// drachmae if confirmed" inline without a second request.
|
|
116
|
+
res.set('Cache-Control', 'no-store');
|
|
117
|
+
res.json({
|
|
118
|
+
reports,
|
|
119
|
+
bounty_table: security.bountyTable(),
|
|
120
|
+
statuses: security.VULN_STATUSES,
|
|
121
|
+
});
|
|
122
|
+
} catch (err) {
|
|
123
|
+
console.error('[gds] GET /security/reports', err);
|
|
124
|
+
res.fail('list_failed', { status: 500, message: 'internal error' });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
// POST /api/bongos/security/reports/:id/confirm
|
|
130
|
+
// Body: { drachmae_awarded?: integer } — defaults to the severity tier
|
|
131
|
+
// bounty if omitted. Marks the report confirmed, stamps confirmed_at,
|
|
132
|
+
// and sets drachmae_awarded.
|
|
133
|
+
//
|
|
134
|
+
// rank: archon — confirms a payout-eligible report.
|
|
135
|
+
router.post(
|
|
136
|
+
'/security/reports/:id/confirm',
|
|
137
|
+
api.requireBuilder,
|
|
138
|
+
api.requireRank('archon'),
|
|
139
|
+
async (req, res) => {
|
|
140
|
+
const id = parseId(req, res, { code: 'bad_report_id', positiveInt: true });
|
|
141
|
+
if (id === null) return;
|
|
142
|
+
const drachmaeRaw = req.body?.drachmae_awarded;
|
|
143
|
+
let drachmaeAwarded = null;
|
|
144
|
+
if (drachmaeRaw !== undefined && drachmaeRaw !== null && drachmaeRaw !== '') {
|
|
145
|
+
const n = Number(drachmaeRaw);
|
|
146
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
147
|
+
return res.fail('bad_drachmae_awarded', 400);
|
|
148
|
+
}
|
|
149
|
+
drachmaeAwarded = n;
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
const report = await security.confirmVulnerabilityReport(id, { drachmaeAwarded });
|
|
153
|
+
res.json({ report });
|
|
154
|
+
} catch (err) {
|
|
155
|
+
if (err && err.code === 'REPORT_NOT_FOUND') {
|
|
156
|
+
return res.fail('report_not_found', 404, { id });
|
|
157
|
+
}
|
|
158
|
+
console.error('[gds] POST /security/reports/:id/confirm', err);
|
|
159
|
+
res.fail('confirm_failed', { status: 500, message: 'internal error' });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
// POST /api/bongos/security/reports/:id/dispute
|
|
165
|
+
// Marks the report disputed and clears drachmae_awarded.
|
|
166
|
+
//
|
|
167
|
+
// rank: archon — dispute adjudication.
|
|
168
|
+
router.post(
|
|
169
|
+
'/security/reports/:id/dispute',
|
|
170
|
+
api.requireBuilder,
|
|
171
|
+
api.requireRank('archon'),
|
|
172
|
+
async (req, res) => {
|
|
173
|
+
const id = parseId(req, res, { code: 'bad_report_id', positiveInt: true });
|
|
174
|
+
if (id === null) return;
|
|
175
|
+
try {
|
|
176
|
+
const report = await security.disputeVulnerabilityReport(id);
|
|
177
|
+
res.json({ report });
|
|
178
|
+
} catch (err) {
|
|
179
|
+
if (err && err.code === 'REPORT_NOT_FOUND') {
|
|
180
|
+
return res.fail('report_not_found', 404, { id });
|
|
181
|
+
}
|
|
182
|
+
console.error('[gds] POST /security/reports/:id/dispute', err);
|
|
183
|
+
res.fail('dispute_failed', { status: 500, message: 'internal error' });
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
// POST /api/bongos/security/reports/:id/fix
|
|
189
|
+
// Marks the report fixed and stamps fixed_at. Does not change
|
|
190
|
+
// fix_task_id — link that separately via /link-fix.
|
|
191
|
+
//
|
|
192
|
+
// rank: archon — fix-confirmation adjudication.
|
|
193
|
+
router.post(
|
|
194
|
+
'/security/reports/:id/fix',
|
|
195
|
+
api.requireBuilder,
|
|
196
|
+
api.requireRank('archon'),
|
|
197
|
+
async (req, res) => {
|
|
198
|
+
const id = parseId(req, res, { code: 'bad_report_id', positiveInt: true });
|
|
199
|
+
if (id === null) return;
|
|
200
|
+
try {
|
|
201
|
+
const report = await security.markVulnerabilityReportFixed(id);
|
|
202
|
+
res.json({ report });
|
|
203
|
+
} catch (err) {
|
|
204
|
+
if (err && err.code === 'REPORT_NOT_FOUND') {
|
|
205
|
+
return res.fail('report_not_found', 404, { id });
|
|
206
|
+
}
|
|
207
|
+
console.error('[gds] POST /security/reports/:id/fix', err);
|
|
208
|
+
res.fail('fix_failed', { status: 500, message: 'internal error' });
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
// POST /api/bongos/security/reports/:id/link-fix
|
|
214
|
+
// Body: { task_id: integer } — attaches a fix-task FK. Doesn't change
|
|
215
|
+
// status (a confirmed report can have a linked fix-task while still
|
|
216
|
+
// open work). 422 if the referenced task doesn't exist.
|
|
217
|
+
//
|
|
218
|
+
// rank: archon — linking a report to its fix-task in the queue.
|
|
219
|
+
router.post(
|
|
220
|
+
'/security/reports/:id/link-fix',
|
|
221
|
+
api.requireBuilder,
|
|
222
|
+
api.requireRank('archon'),
|
|
223
|
+
async (req, res) => {
|
|
224
|
+
const id = parseId(req, res, { code: 'bad_report_id', positiveInt: true });
|
|
225
|
+
if (id === null) return;
|
|
226
|
+
const taskIdRaw = req.body?.task_id;
|
|
227
|
+
const taskId = Number(taskIdRaw);
|
|
228
|
+
if (!Number.isInteger(taskId) || taskId <= 0) {
|
|
229
|
+
return res.fail('bad_task_id', 400);
|
|
230
|
+
}
|
|
231
|
+
try {
|
|
232
|
+
const report = await security.linkVulnerabilityReportFix(id, taskId);
|
|
233
|
+
res.json({ report });
|
|
234
|
+
} catch (err) {
|
|
235
|
+
if (err && err.code === 'REPORT_NOT_FOUND') {
|
|
236
|
+
return res.fail('report_not_found', 404, { id });
|
|
237
|
+
}
|
|
238
|
+
if (err && err.code === 'FIX_TASK_NOT_FOUND') {
|
|
239
|
+
return res.fail('fix_task_not_found', 422, { task_id: taskId });
|
|
240
|
+
}
|
|
241
|
+
if (err && err.code === 'INVALID_FIX_TASK_ID') {
|
|
242
|
+
return res.fail('invalid_fix_task_id', 400);
|
|
243
|
+
}
|
|
244
|
+
console.error('[gds] POST /security/reports/:id/link-fix', err);
|
|
245
|
+
res.fail('link_fix_failed', { status: 500, message: 'internal error' });
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
return router;
|
|
251
|
+
};
|