@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,331 @@
|
|
|
1
|
+
// Session records router — the BFG session-inefficiency evaluator's data plane
|
|
2
|
+
// (ADR 0027). 6D.1 shipped the WRITE path (POST /sessions); 6D.2 adds the READ
|
|
3
|
+
// paths the BFG (a local Claude Code routine, 6D.3) calls to search the corpus
|
|
4
|
+
// and deep-dive interesting sessions:
|
|
5
|
+
//
|
|
6
|
+
// POST /sessions — upload your OWN session digest (6D.1). Owner is
|
|
7
|
+
// forced to the caller; body builder_id is ignored.
|
|
8
|
+
// GET /sessions/mine — your own sessions (self-serve summary list).
|
|
9
|
+
// GET /sessions/search — cross-builder search over session + builder facets
|
|
10
|
+
// (rank/karma/drachmae/tenure). Archon-gated +
|
|
11
|
+
// audited (the BFG principal posture until 6C.1).
|
|
12
|
+
// GET /sessions/:id — one session's full detail for deep-dive. Owner
|
|
13
|
+
// self-serve; cross-builder requires Archon + audit.
|
|
14
|
+
//
|
|
15
|
+
// Cross-builder reads are GETs, which the global audit middleware does NOT
|
|
16
|
+
// instrument — so each writes its own audit_log row (fail-closed: logged BEFORE
|
|
17
|
+
// the data is served). This mirrors the memory router's Archon forensic read.
|
|
18
|
+
// "Archon" stands in for the dedicated BFG service principal until 6C.1 lands
|
|
19
|
+
// (ADR 0026 §6C / ADR 0027) — the gate tightens to the exact principal then.
|
|
20
|
+
//
|
|
21
|
+
// Body size: the global GDS json parser is capped at 64 KB (routes.js); a
|
|
22
|
+
// session digest runs larger, so routes.js skips the global parser for
|
|
23
|
+
// POST /sessions and this router mounts its own (mirroring the memory router).
|
|
24
|
+
|
|
25
|
+
const express = require('express');
|
|
26
|
+
// CARVED into modules/sessions/ (BV1.R82 / ADR 0093 §1): the session-records
|
|
27
|
+
// data plane reaches the kernel ONLY through the published doorway. auth gates +
|
|
28
|
+
// the audit-log writer + the request validators come off `api`; the session
|
|
29
|
+
// records db slice is the module's own `../db`; sumCreditsForTasks (economy) is
|
|
30
|
+
// resolved through the `reward` kernel port, never a direct sibling-module require.
|
|
31
|
+
const api = require('../../../src/module-api');
|
|
32
|
+
const auth = api; // requireBuilder / requireRank live on the doorway surface
|
|
33
|
+
const db = require('../db');
|
|
34
|
+
const seams = api; // resolveOptional('reward') — the economy port, kernel-mediated
|
|
35
|
+
const { validateOrRespond, parseId } = api;
|
|
36
|
+
|
|
37
|
+
const UPLOAD_BODY_LIMIT = '4mb';
|
|
38
|
+
const MAX_DETAIL_TURNS = 5000; // a hard ceiling; ship.js bounds well under this
|
|
39
|
+
|
|
40
|
+
// Disk-fill defense (SR-17 / task 997). The 4 MB body limit + maxItems=5000 cap
|
|
41
|
+
// the SHAPE of the payload, but neither bounds the BYTES a single low-rank
|
|
42
|
+
// builder can persist: an element can be arbitrarily large (only the count was
|
|
43
|
+
// capped), and a digest row lands in jsonb on the single droplet that also hosts
|
|
44
|
+
// the game's Postgres. Sustained POSTs of fat rows fill the disk → outage. The
|
|
45
|
+
// two caps below bound the stored bytes per request; they're sized far above a
|
|
46
|
+
// legitimate digest (each real detail element is a short tool/step record — role,
|
|
47
|
+
// timestamps, token counts, and a snippet hard-capped at 160 chars in ship.js's
|
|
48
|
+
// snippetOf, so ~200-300 B/element; a full 4000-turn digest is ~1.2 MB).
|
|
49
|
+
//
|
|
50
|
+
// - MAX_DETAIL_ELEMENT_BYTES — reject any single detail[] element whose
|
|
51
|
+
// serialized size exceeds this. 4 KB is >10x a real element, so it can't
|
|
52
|
+
// reject a legitimate snippet-bearing turn, but blocks stuffing MBs into one
|
|
53
|
+
// element to dodge the maxItems count cap.
|
|
54
|
+
// - MAX_DETAIL_TOTAL_BYTES — reject the request if the whole detail[] payload
|
|
55
|
+
// serializes larger than this. 2 MB sits under the 4 MB body limit and well
|
|
56
|
+
// above the ~1.2 MB legit ceiling, so it bounds one row's footprint.
|
|
57
|
+
//
|
|
58
|
+
// Residual (NOT closed here): a builder can still spread bytes across many
|
|
59
|
+
// distinct session_id values (one row each). That vector is bounded by the
|
|
60
|
+
// existing per-IP (30/min) and per-session (60/min) write limiters in
|
|
61
|
+
// middleware/rate-limit.js, which already cover POST /sessions — so the sustained
|
|
62
|
+
// write RATE is capped even though the distinct-row COUNT isn't. A per-builder
|
|
63
|
+
// aggregate-bytes guard would need a SUM over session_records on every upload
|
|
64
|
+
// (a heavy query on the hot path); deferred. Retention/rotation of the corpus is
|
|
65
|
+
// also a follow-up — see SR-17 notes.
|
|
66
|
+
const MAX_DETAIL_ELEMENT_BYTES = 4 * 1024; // 4 KB per detail[] element
|
|
67
|
+
const MAX_DETAIL_TOTAL_BYTES = 2 * 1024 * 1024; // 2 MB total detail[] payload
|
|
68
|
+
// The three LIVE ranks (ADR 0018) — deliberately NOT db.RANKS, which is the full
|
|
69
|
+
// 16-entry historical enum. Only these three are ever assigned to a builder, so
|
|
70
|
+
// the search filter validates against them (a query for any other rank is a 400).
|
|
71
|
+
const VALID_RANKS = new Set(['xenos', 'thetes', 'metic', 'archon']);
|
|
72
|
+
|
|
73
|
+
// Per-builder read limiter for the session corpus (mirrors the memory router's
|
|
74
|
+
// forensic-read limiter). Reads aren't covered by the global write limiter.
|
|
75
|
+
const READ_RATE_WINDOW_MS = 60_000;
|
|
76
|
+
const READ_RATE_LIMIT = 60;
|
|
77
|
+
const readBuckets = new Map();
|
|
78
|
+
function readRateLimit(req, res, next) {
|
|
79
|
+
const now = Date.now();
|
|
80
|
+
// Opportunistic prune (only when the map has grown) so idle builders' buckets
|
|
81
|
+
// don't accumulate indefinitely in a long-running process (#541 grade).
|
|
82
|
+
if (readBuckets.size > 256) {
|
|
83
|
+
const cutoffAll = now - READ_RATE_WINDOW_MS;
|
|
84
|
+
for (const [k, b] of readBuckets) {
|
|
85
|
+
if (!b.length || b[b.length - 1] < cutoffAll) readBuckets.delete(k);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const key = String(req.builder.id);
|
|
89
|
+
let bucket = readBuckets.get(key);
|
|
90
|
+
if (!bucket) {
|
|
91
|
+
bucket = [];
|
|
92
|
+
readBuckets.set(key, bucket);
|
|
93
|
+
}
|
|
94
|
+
const cutoff = now - READ_RATE_WINDOW_MS;
|
|
95
|
+
while (bucket.length && bucket[0] < cutoff) bucket.shift();
|
|
96
|
+
if (bucket.length >= READ_RATE_LIMIT) {
|
|
97
|
+
const retryAfter = Math.max(1, Math.ceil((bucket[0] + READ_RATE_WINDOW_MS - now) / 1000));
|
|
98
|
+
res.set('Retry-After', String(retryAfter));
|
|
99
|
+
return res.fail('rate_limited', 429, { scope: 'per-builder-session-read', retry_after_seconds: retryAfter });
|
|
100
|
+
}
|
|
101
|
+
bucket.push(now);
|
|
102
|
+
return next();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// recordSessionRead — audit a cross-builder read. GETs bypass the global audit
|
|
106
|
+
// middleware, so we log explicitly. The caller AWAITS this and, on rejection,
|
|
107
|
+
// returns 500 + withholds the response — so no cross-builder data is ever
|
|
108
|
+
// SERVED without a durable audit row. For /search the audit is written BEFORE
|
|
109
|
+
// the query runs (a failed audit means no query); for /:id the row must be
|
|
110
|
+
// fetched first to know the owner, so the audit precedes only the response, not
|
|
111
|
+
// the DB read (same idiom as the memory router). The true HTTP verb is carried
|
|
112
|
+
// in the body (action + http_method) because audit_log.method is CHECK-
|
|
113
|
+
// constrained to a write verb; auditors query by `action`, not `method`.
|
|
114
|
+
// insertAuditLog already returns a Promise, so we return it directly. It's a
|
|
115
|
+
// KERNEL write, reached through the doorway (api.insertAuditLog), not the
|
|
116
|
+
// module's session-records db slice.
|
|
117
|
+
function recordSessionRead(req, { route, targetBuilderId, target }) {
|
|
118
|
+
return api.insertAuditLog({
|
|
119
|
+
builderId: req.builder.id,
|
|
120
|
+
route,
|
|
121
|
+
method: 'POST',
|
|
122
|
+
requestBodyRedacted: {
|
|
123
|
+
action: 'bfg_session_read',
|
|
124
|
+
http_method: 'GET',
|
|
125
|
+
target_builder_id: targetBuilderId,
|
|
126
|
+
target,
|
|
127
|
+
},
|
|
128
|
+
// Always 200: the row records the INTENT, written before (search) or just
|
|
129
|
+
// before serving (:id) — there is no non-200 path that reaches this call.
|
|
130
|
+
responseStatus: 200,
|
|
131
|
+
ip: req.ip || (req.socket && req.socket.remoteAddress) || null,
|
|
132
|
+
userAgent: (req.headers && req.headers['user-agent']) || null,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
module.exports = function buildSessionsRouter() {
|
|
137
|
+
const router = express.Router();
|
|
138
|
+
const uploadJson = express.json({ limit: UPLOAD_BODY_LIMIT });
|
|
139
|
+
|
|
140
|
+
// rank: any-builder — upload your OWN session digest. Owner is forced to the
|
|
141
|
+
// authenticated caller; the body cannot attribute a record to another builder.
|
|
142
|
+
router.post('/sessions', auth.requireBuilder, uploadJson, async (req, res) => {
|
|
143
|
+
if (validateOrRespond(req, res, {
|
|
144
|
+
session_id: { required: true, type: 'string', maxLength: 256, minLength: 1 },
|
|
145
|
+
task_ids: { type: 'array', maxItems: 500, itemsType: 'integer' },
|
|
146
|
+
total_tokens: { type: 'integer', min: 0 },
|
|
147
|
+
duration_seconds: { type: 'integer', min: 0 },
|
|
148
|
+
started_at: { type: 'string', maxLength: 64 },
|
|
149
|
+
ended_at: { type: 'string', maxLength: 64 },
|
|
150
|
+
detail: { type: 'array', maxItems: MAX_DETAIL_TURNS },
|
|
151
|
+
metrics: { type: 'object' },
|
|
152
|
+
model_usage: { type: 'object' }, // per-model token map for the cost-plus reward (task 1005)
|
|
153
|
+
// drachmae_earned is NOT accepted from the client — computed server-side.
|
|
154
|
+
// model_usage carries TOKEN COUNTS only; the reward USD is priced server-side.
|
|
155
|
+
})) return;
|
|
156
|
+
|
|
157
|
+
const body = req.body || {};
|
|
158
|
+
// Format guard: session_id lands in an indexed column the BFG searches, and
|
|
159
|
+
// the canonical value is a UUID-shaped token. Reject anything else so a
|
|
160
|
+
// direct API caller can't pollute the corpus with newlines / path-like junk.
|
|
161
|
+
if (!/^[A-Za-z0-9_-]{1,256}$/.test(body.session_id)) {
|
|
162
|
+
return res.fail('bad_session_id', 400);
|
|
163
|
+
}
|
|
164
|
+
// Empty-session guard: a digest with 0 total tokens carries no real LLM work
|
|
165
|
+
// — it's an aborted start or a failed/empty subagent spawn (e.g. a grader
|
|
166
|
+
// worker that 429'd: one synthetic turn, no usage). These have nothing for
|
|
167
|
+
// the BFG to analyze and only skew the corpus aggregates, so we never log
|
|
168
|
+
// them. Benign 200 skip (not an error) so the best-effort upload-on-ship
|
|
169
|
+
// path treats it as a clean no-op.
|
|
170
|
+
if (!(Number(body.total_tokens) > 0)) {
|
|
171
|
+
return res.status(200).json({ skipped: true, reason: 'empty' });
|
|
172
|
+
}
|
|
173
|
+
// Byte-bound the detail[] payload (SR-17). maxItems already capped the
|
|
174
|
+
// element COUNT; these cap the element + total BYTES so one upload can't
|
|
175
|
+
// write a fat jsonb row that fills the droplet's disk. We measure the
|
|
176
|
+
// serialized size element-by-element (so we can name the offending index)
|
|
177
|
+
// and accumulate the total. Returns 413 (payload too large) with the
|
|
178
|
+
// existing { error, message } envelope.
|
|
179
|
+
const detailArr = Array.isArray(body.detail) ? body.detail : [];
|
|
180
|
+
let detailTotalBytes = 0;
|
|
181
|
+
for (let idx = 0; idx < detailArr.length; idx++) {
|
|
182
|
+
const elemBytes = Buffer.byteLength(JSON.stringify(detailArr[idx]) || 'null', 'utf8');
|
|
183
|
+
if (elemBytes > MAX_DETAIL_ELEMENT_BYTES) {
|
|
184
|
+
return res.fail('detail_element_too_large', { status: 413, message: `detail[${idx}] is ${elemBytes} bytes; the per-element cap is ${MAX_DETAIL_ELEMENT_BYTES} bytes` });
|
|
185
|
+
}
|
|
186
|
+
detailTotalBytes += elemBytes;
|
|
187
|
+
if (detailTotalBytes > MAX_DETAIL_TOTAL_BYTES) {
|
|
188
|
+
return res.fail('detail_payload_too_large', { status: 413, message: `detail[] exceeds the ${MAX_DETAIL_TOTAL_BYTES}-byte total cap` });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const requestedTaskIds = Array.isArray(body.task_ids)
|
|
192
|
+
? body.task_ids.map(Number).filter(Number.isFinite)
|
|
193
|
+
: [];
|
|
194
|
+
try {
|
|
195
|
+
// Keep only task IDs the builder actually claimed — a direct API caller
|
|
196
|
+
// can't associate (and thus pollute the corpus with) others' work.
|
|
197
|
+
const taskIds = await db.filterTaskIdsClaimedBy(req.builder.id, requestedTaskIds);
|
|
198
|
+
// Drachmae is the AUTHORITATIVE credit_log delta for this upload's owned
|
|
199
|
+
// task(s), computed server-side — never trusted from the client.
|
|
200
|
+
const drachmaeEarned = await seams.resolveOptional('reward').sumCreditsForTasks(req.builder.id, taskIds);
|
|
201
|
+
// Dedup: total_tokens has its own column, so strip it from the metrics
|
|
202
|
+
// jsonb to avoid two sources of truth in the same row.
|
|
203
|
+
const metrics = body.metrics && typeof body.metrics === 'object' ? { ...body.metrics } : {};
|
|
204
|
+
delete metrics.total_tokens;
|
|
205
|
+
delete metrics.model_usage; // promoted to its own column; avoid two copies
|
|
206
|
+
const modelUsage = body.model_usage && typeof body.model_usage === 'object'
|
|
207
|
+
? body.model_usage : {};
|
|
208
|
+
// upsert + cost-plus token reward in ONE transaction (task 1005). The
|
|
209
|
+
// reward USD is priced server-side from modelUsage's TOKEN COUNTS via
|
|
210
|
+
// llm-pricing.js — the client never sends a dollar figure.
|
|
211
|
+
const record = await db.upsertSessionRecordWithReward({
|
|
212
|
+
sessionId: body.session_id,
|
|
213
|
+
builderId: req.builder.id, // owner = caller, never the body
|
|
214
|
+
taskIds,
|
|
215
|
+
drachmaeEarned,
|
|
216
|
+
totalTokens: body.total_tokens ?? 0,
|
|
217
|
+
durationSeconds: body.duration_seconds ?? null,
|
|
218
|
+
startedAt: body.started_at ?? null,
|
|
219
|
+
endedAt: body.ended_at ?? null,
|
|
220
|
+
detail: detailArr,
|
|
221
|
+
metrics,
|
|
222
|
+
modelUsage,
|
|
223
|
+
});
|
|
224
|
+
if (!record) {
|
|
225
|
+
// Ownership-guard no-op: the session_id exists but belongs to another
|
|
226
|
+
// builder. Report a benign skip (don't confirm the foreign ownership).
|
|
227
|
+
return res.status(200).json({ skipped: true });
|
|
228
|
+
}
|
|
229
|
+
res.status(201).json({ session: record, token_reward: record.tokenReward });
|
|
230
|
+
} catch (err) {
|
|
231
|
+
console.error('[gds] POST /sessions', err);
|
|
232
|
+
res.fail('upload_failed', 500);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// GET /sessions/search + /sessions/mine are declared BEFORE /sessions/:id so
|
|
237
|
+
// Express matches the literal paths first (the numeric :id never swallows them).
|
|
238
|
+
|
|
239
|
+
// rank: archon — cross-builder corpus search (BFG-principal posture until 6C.1).
|
|
240
|
+
router.get('/sessions/search', auth.requireBuilder, auth.requireRank('archon'), readRateLimit, async (req, res) => {
|
|
241
|
+
const q = req.query || {};
|
|
242
|
+
const rank = q.rank ? String(q.rank) : null;
|
|
243
|
+
if (rank && !VALID_RANKS.has(rank)) {
|
|
244
|
+
return res.fail('bad_rank', 400, { valid: Array.from(VALID_RANKS) });
|
|
245
|
+
}
|
|
246
|
+
const numOrNull = (v) => {
|
|
247
|
+
if (v == null) return null;
|
|
248
|
+
const n = Number(v);
|
|
249
|
+
return Number.isFinite(n) ? n : null;
|
|
250
|
+
};
|
|
251
|
+
const filters = {
|
|
252
|
+
rank,
|
|
253
|
+
minKarma: numOrNull(q.min_karma),
|
|
254
|
+
minDrachmae: numOrNull(q.min_drachmae),
|
|
255
|
+
minTokens: numOrNull(q.min_tokens),
|
|
256
|
+
minToolErrors: numOrNull(q.min_tool_errors),
|
|
257
|
+
minDurationSec: numOrNull(q.min_duration_seconds),
|
|
258
|
+
maxTenureDays: numOrNull(q.max_tenure_days),
|
|
259
|
+
order: q.order ? String(q.order) : 'recent',
|
|
260
|
+
limit: q.limit,
|
|
261
|
+
offset: q.offset,
|
|
262
|
+
};
|
|
263
|
+
try {
|
|
264
|
+
// Audit the cross-builder search BEFORE the query runs: a failed audit
|
|
265
|
+
// write means the corpus is never queried (true fail-closed — no read
|
|
266
|
+
// without a durable record).
|
|
267
|
+
await recordSessionRead(req, {
|
|
268
|
+
route: '/api/bongos/sessions/search',
|
|
269
|
+
targetBuilderId: null,
|
|
270
|
+
target: `search rank=${rank || '*'} order=${filters.order} offset=${db.clampSessionOffset(filters.offset)}`,
|
|
271
|
+
});
|
|
272
|
+
// Page + corpus-wide tally in parallel. `totals` reflects EVERY session
|
|
273
|
+
// matching the filter (not just this page), so the Ledger's stats stay
|
|
274
|
+
// stable as the viewer pages; `total` drives the pager's "page X of Y".
|
|
275
|
+
const [sessions, totals] = await Promise.all([
|
|
276
|
+
db.searchSessions(filters),
|
|
277
|
+
db.summarizeSessions(filters),
|
|
278
|
+
]);
|
|
279
|
+
res.json({
|
|
280
|
+
sessions,
|
|
281
|
+
count: sessions.length,
|
|
282
|
+
total: totals.total,
|
|
283
|
+
totals,
|
|
284
|
+
limit: db.clampSessionLimit(filters.limit),
|
|
285
|
+
offset: db.clampSessionOffset(filters.offset),
|
|
286
|
+
});
|
|
287
|
+
} catch (err) {
|
|
288
|
+
console.error('[gds] GET /sessions/search', err);
|
|
289
|
+
res.fail('search_failed', 500);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// rank: any-builder — your OWN sessions (self-serve; no audit needed).
|
|
294
|
+
router.get('/sessions/mine', auth.requireBuilder, readRateLimit, async (req, res) => {
|
|
295
|
+
try {
|
|
296
|
+
const sessions = await db.listSessionsByBuilder(req.builder.id, req.query.limit);
|
|
297
|
+
res.json({ sessions, count: sessions.length });
|
|
298
|
+
} catch (err) {
|
|
299
|
+
console.error('[gds] GET /sessions/mine', err);
|
|
300
|
+
res.fail('list_failed', 500);
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
// rank: any-builder — own session full detail (deep-dive); cross-builder fetch
|
|
305
|
+
// requires Archon + a fail-closed audit row (BFG-principal posture until 6C.1).
|
|
306
|
+
router.get('/sessions/:id', auth.requireBuilder, readRateLimit, async (req, res) => {
|
|
307
|
+
const id = parseId(req, res, { code: 'bad_session_id', positiveInt: true });
|
|
308
|
+
if (id === null) return;
|
|
309
|
+
try {
|
|
310
|
+
const session = await db.getSessionById(id);
|
|
311
|
+
if (!session) return res.fail('not_found', 404);
|
|
312
|
+
const isOwner = String(session.builder_id) === String(req.builder.id);
|
|
313
|
+
if (!isOwner) {
|
|
314
|
+
// Non-owner, non-Archon: return 404 (NOT 403) so the response can't be
|
|
315
|
+
// used as an existence oracle for sequential session ids.
|
|
316
|
+
if (req.builder.rank !== 'archon') return res.fail('not_found', 404);
|
|
317
|
+
await recordSessionRead(req, {
|
|
318
|
+
route: '/api/bongos/sessions/:id',
|
|
319
|
+
targetBuilderId: session.builder_id,
|
|
320
|
+
target: `session:${id}`,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
res.json({ session });
|
|
324
|
+
} catch (err) {
|
|
325
|
+
console.error('[gds] GET /sessions/:id', err);
|
|
326
|
+
res.fail('fetch_failed', 500);
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
return router;
|
|
331
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# `status-ui` module — the public status dashboard ("The Watch")
|
|
2
|
+
|
|
3
|
+
> A CORE-domain carve (BV1.R84, [ADR 0093](../../docs/adr/<redacted>.md) §1) — the **first WEB-SURFACE module** ([02-module-map §6](../../docs/design/modular-architecture/02-module-map.md): "a web surface is first-class"). `default: true` — a Cloud Bongos instance ships its status page like it ships its hall, so it mounts unconditionally unless an instance disables it.
|
|
4
|
+
|
|
5
|
+
Owns the public build-status dashboard served at **`status.<apex>`** (`status.example.com`) — the live up/down banner, version-progress rollups, cost summary, recent ships, the leaderboard, and the kinds-of-work ecosystem fingerprint. A no-framework page (`status.js`) that polls the read-only `/api/gds/public/*` surface every 60s.
|
|
6
|
+
|
|
7
|
+
## The shape: a static surface, not a backend domain
|
|
8
|
+
|
|
9
|
+
Unlike every prior tranche-2 carve (economy/ideas/security/…), this module has **no `.js`, no `db.js` slice, no kernel port, and no routes**. It is purely:
|
|
10
|
+
- `public/` — the static dashboard (HTML/CSS/JS/cursors/snapshots), moved verbatim from the old repo-root `public-status/`.
|
|
11
|
+
- `module.json` — declares one **`contributes.webSurfaces`** entry `{ host: "status.", dir: "public" }`.
|
|
12
|
+
|
|
13
|
+
## The serving seam (how a web surface reaches its host with no core edit)
|
|
14
|
+
|
|
15
|
+
The loader exposes `moduleWebSurfaces({ isEnabled })` ([`src/module-loader/loader.js`](../../src/module-loader/loader.js)) — the Host-routed twin of `hallWidgetScripts`/`mountModuleRoutes`. It returns `[{ key, host, dir(abs) }]` for each enabled module that declares `webSurfaces` **and** ships the directory on disk. `src/bongos/serve-internal.js` iterates that set and serves each surface on its `Host:` prefix with the **same** machinery the status page always used:
|
|
16
|
+
- the in-memory **content-hash-stamped** index (`buildStampedHtml`, #521 — defeats Cloudflare's 4h TTL),
|
|
17
|
+
- the per-instance **branding/theme injection** (`injectBrandingInto`),
|
|
18
|
+
- fall-through to `express.static` for assets.
|
|
19
|
+
|
|
20
|
+
`serve-internal.js` names **no module key** (kernel stays module-agnostic, [ADR 0083](../../docs/adr/<redacted>.md) §Decision #4); it routes purely off the manifest-declared `host` prefix. The `isStatusHost` export stays the literal `status.` predicate the entrypoints (`server.js`/`src/platform-server.js`) use to keep their apex tail off the status host; **inside** `mountInternalSurfaces` the generic `isModuleSurfaceHost` (any enabled web-surface host) is used, so the next carved surface (hall-UI, R85) needs no new guard.
|
|
21
|
+
|
|
22
|
+
## The boundary
|
|
23
|
+
|
|
24
|
+
This module reaches **nothing** in core (no doorway require — it has no JS). Core, in turn, must never `require()` a file in here — `serve-internal.js` resolves the surface through `loader.moduleWebSurfaces`, never an import of `modules/status-ui/*`. Both directions are enforced by the BV1.R44/R45 fitness checks.
|
|
25
|
+
|
|
26
|
+
## The data it renders STAYS shared core (the judgment call)
|
|
27
|
+
|
|
28
|
+
The `/api/gds/public/*` read endpoints the dashboard polls (`/public/uptime`, `/public/progress`, `/public/cost-summary`, `/public/grades`, `/public/recent-shipped`, `/public/leaderboard`, `/public/analytics/ecosystem`, `/public/tasks|ideas|blockers/:id`, plus `/versions/:id/done-when`) **did not move** — they live in `src/bongos/routes/public.js` and are consumed by the hall and the **off-box GitHub-Pages mirror** too, not just this surface. A public read shared by multiple surfaces is correctly core/shared, not status-exclusive (the same call the economy/ideas carves made for `routes/public.js`'s inline reads). So the carve moves the *surface*, not the reads it happens to render.
|
|
29
|
+
|
|
30
|
+
## Off-box mirror (operational)
|
|
31
|
+
|
|
32
|
+
The LIVE page is served **off the droplet** for outage resilience ([ADR 0029](../../docs/adr/<redacted>.md)) — GitHub Pages from `example-owner/example-status`, fed by `scripts/status-mirror-sync.js`. That script (status-UI domain tooling that travels with its domain but stays a CLI under `scripts/`, the sessions/autonomy precedent) was re-pointed at `modules/status-ui/public/`. **Follow-up:** `.github/workflows/sync-status-mirror.yml` still triggers on `public-status/**` and must be re-pointed at `modules/status-ui/public/**` by an owner/Archon (the GitHub App can't push workflow files — learning 107).
|
|
33
|
+
|
|
34
|
+
## Files & tooling
|
|
35
|
+
|
|
36
|
+
| Path | What |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `public/index.html` · `public/status.js` · `public/style.css` | the dashboard (no build step, no framework) |
|
|
39
|
+
| `public/cursors/` · `public/snapshots/` | bronze cursors + the world-render snapshots the page shows |
|
|
40
|
+
| `public/README.md` | the surface's own notes (off-box mirror, asset cache-busting) |
|
|
41
|
+
| `module.json` | `contributes.webSurfaces: [{ host: "status.", dir: "public" }]`; no port, no routes |
|
|
42
|
+
|
|
43
|
+
Generators that WRITE into this surface live under `scripts/` and were re-pointed: `scripts/art/gen-cursors.py` (cursors), `scripts/snapshots/render-*.mjs` (snapshots), `scripts/status-mirror-sync.js` (off-box publish).
|
|
44
|
+
|
|
45
|
+
## Tests
|
|
46
|
+
|
|
47
|
+
The loader seam is covered in `tests/module_loader.mjs` (`moduleWebSurfaces` — enabled lists, disabled vanishes, declared-but-not-shipped skipped, plus the live status-ui surface); the manifest `webSurfaces` validation in `tests/module_manifest.mjs`; the carve discovery-key membership in `tests/fitness.mjs` / `tests/module_loader.mjs` / `tests/modules.mjs`; and the carve proof in `scripts/gds/coreB-carve-proof.sh` (leg 4h).
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"key": "status-ui",
|
|
3
|
+
"title": "Status dashboard (\"The Watch\")",
|
|
4
|
+
"description": "The public build-status dashboard served at status.<apex> (status.amazonprimea.com) — the live up/down banner, version-progress rollups, cost summary, recent ships, leaderboard, and the ecosystem fingerprint, all polling the read-only /api/gds/public/* surface every 60s. A WEB-SURFACE core-domain module carved out of the GDS core in BV1.R84 (ADR 0093 §1; 02-module-map §6 — a web surface is first-class). default-on: a Cloud Bongos instance ships its status page like it ships its hall. Registers no port and contributes no routes — it declares a webSurface (host prefix + static dir) the loader hands serve-internal, which serves the module's public/ dir on the matching host exactly as it served public-status/ before. The public read endpoints it renders stay SHARED core in routes/public.js (the hall + the off-box mirror read them too).",
|
|
5
|
+
"coreVersion": "^1.11.0",
|
|
6
|
+
"default": true,
|
|
7
|
+
"contributes": {
|
|
8
|
+
"webSurfaces": [
|
|
9
|
+
{ "host": "status.", "dir": "public" }
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"provides": [],
|
|
13
|
+
"consumes": []
|
|
14
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# `modules/status-ui/public/` — the status dashboard ("The Watch")
|
|
2
|
+
|
|
3
|
+
These files are the source of `status.example.com`. The surface moved here from `public-status/` in **BV1.R84** when the status dashboard became a first-class module ([ADR 0093](../../../docs/adr/<redacted>.md) §1); the loader's web-surface seam serves this `public/` dir on the `status.` host (see [`../CLAUDE.md`](../CLAUDE.md)). As of **#566 / [ADR 0029](../../../docs/adr/<redacted>.md)** they are **mirrored OFF-BOX** so the status page survives a droplet outage.
|
|
4
|
+
|
|
5
|
+
## Why off-box
|
|
6
|
+
|
|
7
|
+
On 2026-06-03 the droplet was powered off (a failed payment) and this page — served by the *same* Node process as the game — went dark with it. A status page must not share fate with the system it reports on.
|
|
8
|
+
|
|
9
|
+
## Where it lives now
|
|
10
|
+
|
|
11
|
+
- **Off-box mirror:** **[`example-owner/example-status`](https://github.com/example-owner/example-status)** → served by **GitHub Pages** (separate infrastructure from the DigitalOcean droplet). After the DNS cutover, `status.example.com` points there.
|
|
12
|
+
- **This copy (droplet):** remains the origin/source of truth for the page markup and the fallback until the DNS cutover is confirmed. Once the off-box mirror is canonical it can be deprecated in a follow-up.
|
|
13
|
+
|
|
14
|
+
## How the off-box page stays truthful during an outage
|
|
15
|
+
|
|
16
|
+
The mirror is a port of these files with three changes:
|
|
17
|
+
|
|
18
|
+
1. **Availability banner (always truthful):** a top strip reads the external prober's `status.json` from the off-box `status-data` branch (`raw.githubusercontent.com`) — so it shows the *real* up/down even when the droplet (and its API) are down.
|
|
19
|
+
2. **Dev panels (degrade gracefully):** `status.js`'s `API` base points at the absolute droplet origin (`https://example.com`); `/api/bongos/public/*` now sends `<redacted>: *` (see `src/bongos/routes/public.js`) so the panels load cross-origin. Each fetch already `.catch(() => null)`, so when the droplet is down the panels show their empty state instead of breaking the page.
|
|
20
|
+
3. **Assets are relative** so the page works at both the GitHub Pages URL and the custom domain.
|
|
21
|
+
|
|
22
|
+
## Probing & alerting
|
|
23
|
+
|
|
24
|
+
- **Alerting:** `.github/workflows/status-probe.yml` (this repo, #565) probes from outside every 5 min and **emails on a confirmed outage** — the "never surprised again" path.
|
|
25
|
+
- **Page data:** the off-box repo runs its own **data-only** prober (no alert, to avoid double-alerting) that publishes `status.json` for the banner.
|
|
26
|
+
|
|
27
|
+
## `uptime-poller.js` decision (ADR 0029)
|
|
28
|
+
|
|
29
|
+
[`src/bongos/uptime-poller.js`](../../../src/bongos/uptime-poller.js) is **retained as an INTERNAL component-liveness signal** (can the Node process reach its own DB?). It is **no longer the public source of truth** for availability — a monitor inside the monitored process cannot witness its own death. The public truth is now the **external** prober (#565) + this off-box page. The in-process poller stays because the internal "is my DB reachable" datapoint is still useful and cheap; removing it is not warranted.
|
|
Binary file
|
|
Binary file
|