@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,506 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
// Intra-module + the published doorway — a module never requires a core internal.
|
|
3
|
+
const api = require('../../../src/module-api');
|
|
4
|
+
const auth = api;
|
|
5
|
+
const db = require('../db');
|
|
6
|
+
// The evergreen newcomer-chore restock carved into modules/onboarding/ (BV1.R81 /
|
|
7
|
+
// ADR 0093 §1): POST /claims restocks the chore shelf the instant one is claimed,
|
|
8
|
+
// through the `onboarding` kernel port (seams.resolveOptional('onboarding')) —
|
|
9
|
+
// never a direct require of a module file. The doorway re-exports the seam fns.
|
|
10
|
+
const seams = api;
|
|
11
|
+
const { validateOrRespond, LIMITS, parseId } = api;
|
|
12
|
+
|
|
13
|
+
// V3.R33 (#254): input validation guards. Length caps + shape checks at the
|
|
14
|
+
// top of every write handler. Schemas describe KNOWN-field constraints only —
|
|
15
|
+
// extra unknown fields pass through (supervisor-permissive; see _helpers.js).
|
|
16
|
+
|
|
17
|
+
const CLAIM_OUTCOMES = ['shipped', 'abandoned', 'partial'];
|
|
18
|
+
|
|
19
|
+
// Which session a fresh claim is bound to. A CLI claim binds to the calling
|
|
20
|
+
// session (creator_session_id) so a later ship from a DIFFERENT terminal trips
|
|
21
|
+
// CLAIM_SESSION_MISMATCH — that guard catches a builder accidentally shipping
|
|
22
|
+
// from the wrong worktree. But a claim made from the WEB UI (#616) has no
|
|
23
|
+
// working session: the builder claims in the browser, then opens a terminal to
|
|
24
|
+
// do the work. Binding to the throwaway web session would force every such
|
|
25
|
+
// builder to `release --force` before they could ship. So a web claim passes
|
|
26
|
+
// bind_session=false and is created session-UNBOUND (creator_session_id=null),
|
|
27
|
+
// which makes the mismatch check short-circuit and lets any of the builder's
|
|
28
|
+
// own CLI sessions adopt and ship it. Default true keeps every CLI caller
|
|
29
|
+
// (which omits the flag) on the existing bind-to-session behaviour.
|
|
30
|
+
function resolveCreatorSessionId(bindSession, sessionId) {
|
|
31
|
+
return bindSession === false ? null : (sessionId ?? null);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// V4.R14 (#952): the way-forward hint on a TASK_NOT_READY 409. A 'backlog' task
|
|
35
|
+
// is promoted; any other non-ready status (blocked/active/…) is explained. Pure +
|
|
36
|
+
// exported so the message is pinned by a test without standing up a route.
|
|
37
|
+
function taskNotReadyHint(taskId, currentStatus) {
|
|
38
|
+
const idNum = Number(taskId);
|
|
39
|
+
return currentStatus === 'backlog'
|
|
40
|
+
? `Task #${idNum} is in 'backlog' — promote it first: POST /api/bongos/tasks/${idNum}/promote (Archon), then claim.`
|
|
41
|
+
: `Task #${idNum} is '${currentStatus}', not 'ready' — only 'ready' tasks are claimable (promote applies to 'backlog': POST /api/bongos/tasks/${idNum}/promote).`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// task 1642 — the pure session-scoped one-active-claim decision. Working two
|
|
45
|
+
// tasks from one worktree means every commit lands on the single branch that
|
|
46
|
+
// worktree owns; /builder-ship publishes the whole branch, so shipping one task
|
|
47
|
+
// drags the other's commits with it (commingled ships). The structural cure: a
|
|
48
|
+
// CLI session (≈ one worktree) may hold at most ONE active claim at a time.
|
|
49
|
+
//
|
|
50
|
+
// Keyed on creator_session_id, NOT builder id — a builder may run many sessions
|
|
51
|
+
// in parallel, each with its own worktree and exactly one claim; that norm must
|
|
52
|
+
// keep working. Session-scoped, all ranks (generalizes the old Xenos-only,
|
|
53
|
+
// builder-scoped gateNewcomerClaim).
|
|
54
|
+
//
|
|
55
|
+
// NULL-session handling: a web claim (bind_session=false) stores
|
|
56
|
+
// creator_session_id=NULL and is adoptable by any of the builder's CLI sessions.
|
|
57
|
+
// We MUST skip the check when the *incoming* claim has no session (nothing to
|
|
58
|
+
// scope to) — the caller passes creatorSessionId=null and we allow. The DB
|
|
59
|
+
// helper that feeds activeClaimsForSession already filters to the SAME non-null
|
|
60
|
+
// session, so a pile of NULL-session web claims can never count against a CLI
|
|
61
|
+
// session either.
|
|
62
|
+
//
|
|
63
|
+
// Pure + exported so the decision is unit-testable without a DB or a route.
|
|
64
|
+
// Returns { refuse, inFlightTaskId, inFlightTitle, reason }.
|
|
65
|
+
function shouldRefuseSessionClaim({ activeClaimsForSession, creatorSessionId }) {
|
|
66
|
+
// No session to scope to (web/unbound claim, or a CLI caller with no session):
|
|
67
|
+
// there is nothing this guard can key on — let it through. The per-task unique
|
|
68
|
+
// index and the newcomer gate still apply.
|
|
69
|
+
if (!creatorSessionId) {
|
|
70
|
+
return { refuse: false, inFlightTaskId: null, inFlightTitle: null, reason: null };
|
|
71
|
+
}
|
|
72
|
+
const claims = Array.isArray(activeClaimsForSession) ? activeClaimsForSession : [];
|
|
73
|
+
// Defence in depth: only count claims that actually belong to THIS session and
|
|
74
|
+
// are genuinely session-bound. A NULL-session row must never trip the block.
|
|
75
|
+
const inFlight = claims.find(
|
|
76
|
+
(c) => c && c.creator_session_id != null && c.creator_session_id === creatorSessionId
|
|
77
|
+
);
|
|
78
|
+
if (inFlight) {
|
|
79
|
+
return {
|
|
80
|
+
refuse: true,
|
|
81
|
+
inFlightTaskId: inFlight.task_id ?? null,
|
|
82
|
+
inFlightTitle: inFlight.title ?? null,
|
|
83
|
+
reason: 'session_already_has_active_claim',
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return { refuse: false, inFlightTaskId: null, inFlightTitle: null, reason: null };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// task 1642 — the route middleware that enforces the rule above. FAIL-CLOSED:
|
|
90
|
+
// this is a hard correctness block (it stops commingled ships), so if the
|
|
91
|
+
// session-active-claim lookup throws we REFUSE rather than silently allow. That
|
|
92
|
+
// is the deliberate inverse of gateNewcomerClaim's fail-open posture (onboarding
|
|
93
|
+
// plumbing must never brick a claim; this concurrency guard must never let a
|
|
94
|
+
// second claim slip through on an error). A NULL incoming session short-circuits
|
|
95
|
+
// to allow (handled inside shouldRefuseSessionClaim) — web/unbound claims and
|
|
96
|
+
// session-less CLI callers are unaffected.
|
|
97
|
+
async function gateOneActiveClaimPerSession(req, res, next) {
|
|
98
|
+
// bind_session=false ⇒ session-UNBOUND web claim: resolveCreatorSessionId
|
|
99
|
+
// will store NULL, so there is nothing to scope to. Mirror that here so we
|
|
100
|
+
// never do a needless lookup and never block a web claim.
|
|
101
|
+
const creatorSessionId = resolveCreatorSessionId(req.body?.bind_session, req.gdsSession?.session_id);
|
|
102
|
+
if (!creatorSessionId) return next();
|
|
103
|
+
let activeClaimsForSession;
|
|
104
|
+
try {
|
|
105
|
+
activeClaimsForSession = await db.getActiveClaimsForSession(creatorSessionId);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
// FAIL-CLOSED. A lookup failure must not let a commingling second claim land.
|
|
108
|
+
console.error('[gds] gateOneActiveClaimPerSession lookup failed (failing closed):', err);
|
|
109
|
+
return res.fail('session_claim_check_failed', { status: 409, message: 'Could not verify this session has no other claim in flight. Try again, or start a fresh session/worktree for this task.' });
|
|
110
|
+
}
|
|
111
|
+
const decision = shouldRefuseSessionClaim({ activeClaimsForSession, creatorSessionId });
|
|
112
|
+
if (decision.refuse) {
|
|
113
|
+
const n = decision.inFlightTaskId;
|
|
114
|
+
return res.fail('session_already_has_active_claim', { status: 409, message: `This session already has task ${n} in flight — ship or release it first, or start a new session/worktree for this one.`, details: { active_task_id: n, active_task_title: decision.inFlightTitle, what_to_do: `Run /builder-ship ${n} (or /builder-release ${n}) before claiming new work, or open a fresh worktree/session for this task.` } });
|
|
115
|
+
}
|
|
116
|
+
next();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Newcomer claim gate. Keeps a fresh arrival focused: ship thy current work
|
|
120
|
+
// before opening another. This applies only while the builder is a Xenos —
|
|
121
|
+
// once they graduate to Thetes (after 3 shipped tasks, #692 / ADR 0034) they
|
|
122
|
+
// may juggle claims freely.
|
|
123
|
+
//
|
|
124
|
+
// History: until #766 this also enforced a primer_read stage ("read the primer
|
|
125
|
+
// before claiming"). That gate was removed when the primer requirement was
|
|
126
|
+
// dropped from the Xenos path; the one-claim-at-a-time rule below is all that
|
|
127
|
+
// remains, and it's now keyed on the live rank rather than an onboarding stage.
|
|
128
|
+
async function gateNewcomerClaim(req, res, next) {
|
|
129
|
+
try {
|
|
130
|
+
// Only Xenos are held to the one-claim-at-a-time rule. Everyone else
|
|
131
|
+
// (Thetes, Metic, Archon — and the no-rank fail-open below) passes through.
|
|
132
|
+
if (!req.builder || req.builder.rank !== 'xenos') return next();
|
|
133
|
+
const active = await db.getActiveClaimsForBuilder(req.builder.id);
|
|
134
|
+
if (active.length > 0) {
|
|
135
|
+
const top = active[0];
|
|
136
|
+
return res.fail('newcomer_must_ship_first', { status: 403, message: 'Ship thy current claim before opening another. The first work must be carried through.', details: { active_claim_id: top.claim_id, active_task_id: top.task_id, active_task_title: top.title, what_to_do: `Run /builder-ship ${top.task_id} (or /builder-release ${top.task_id} to abandon it) before claiming new work.` } });
|
|
137
|
+
}
|
|
138
|
+
next();
|
|
139
|
+
} catch (err) {
|
|
140
|
+
console.error('[gds] gateNewcomerClaim failed:', err);
|
|
141
|
+
// Fail open — onboarding plumbing must never brick a claim attempt.
|
|
142
|
+
next();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
module.exports = function buildClaimsRouter() {
|
|
147
|
+
const router = express.Router();
|
|
148
|
+
|
|
149
|
+
// rank: any-builder — own work (claim a ready task); Xenos additionally filtered
|
|
150
|
+
// to newcomer_friendly rows inside db.claimTask (returns rank_too_low_for_task
|
|
151
|
+
// 403). Supervisor hot path (preserved per CRITICAL §4 — no requireRank).
|
|
152
|
+
// gateNewcomerClaim enforces the newcomer focus rule — a Xenos must ship
|
|
153
|
+
// their current claim before opening another (#766; the prior primer gate
|
|
154
|
+
// was removed there).
|
|
155
|
+
// task 1642: gateOneActiveClaimPerSession is the session-scoped, all-rank,
|
|
156
|
+
// FAIL-CLOSED hard block on a second active claim in the same session (one
|
|
157
|
+
// worktree → one claim → no commingled ships). It runs BEFORE the Xenos-only
|
|
158
|
+
// gateNewcomerClaim, which stays for its rank-graduation messaging.
|
|
159
|
+
router.post('/claims', auth.requireBuilder, gateOneActiveClaimPerSession, gateNewcomerClaim, async (req, res) => {
|
|
160
|
+
if (validateOrRespond(req, res, {
|
|
161
|
+
task_id: { required: true },
|
|
162
|
+
worktree_name: { type: 'string', maxLength: LIMITS.WORKTREE_NAME },
|
|
163
|
+
head_sha: { type: 'string', maxLength: 64 },
|
|
164
|
+
bind_session: { type: 'boolean' },
|
|
165
|
+
// touches[] cleanup [5/8] (task 880): the autonomous --parallel runner
|
|
166
|
+
// sets this true so file-footprint overlap is a HARD 409. Default false:
|
|
167
|
+
// an interactive single-human claim only WARNS (git merge is the real
|
|
168
|
+
// collision detector — ADR 0017).
|
|
169
|
+
enforce_touches: { type: 'boolean' },
|
|
170
|
+
})) return;
|
|
171
|
+
const { task_id: taskId, worktree_name: worktreeName, head_sha: headSha, bind_session: bindSession, enforce_touches: enforceTouches } = req.body || {};
|
|
172
|
+
// Belt-and-braces — task_id must coerce to a finite number. Older calls
|
|
173
|
+
// sent string ints (Number.isFinite passes both); reject NaN/garbage.
|
|
174
|
+
if (!Number.isFinite(Number(taskId))) {
|
|
175
|
+
return res.fail('validation_failed', 400, [{ field: 'task_id', reason: 'wrong_type', expected: 'integer' }]);
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
const claimResult = await db.claimTask({
|
|
179
|
+
taskId: Number(taskId),
|
|
180
|
+
builderId: req.builder.id,
|
|
181
|
+
worktreeName: worktreeName ?? null,
|
|
182
|
+
headSha: headSha ?? null,
|
|
183
|
+
creatorSessionId: resolveCreatorSessionId(bindSession, req.gdsSession?.session_id),
|
|
184
|
+
enforceOverlap: enforceTouches === true,
|
|
185
|
+
});
|
|
186
|
+
const { just_unlocked: justUnlocked, overlap_warning: overlapWarning, ...claim } = claimResult;
|
|
187
|
+
const task = await db.getTask(Number(taskId));
|
|
188
|
+
// task 1168: keep the evergreen newcomer-chore shelf full. If this claim
|
|
189
|
+
// took a chore instance, stamp a replacement NOW (before responding) so
|
|
190
|
+
// the next newcomer always finds one ready — the owner's requirement that
|
|
191
|
+
// a fresh one is there the instant one is CLAIMED, not when completed.
|
|
192
|
+
// Best-effort + fail-open: a restock failure must never break the claim
|
|
193
|
+
// (it self-heals on the next claim, and the manual seeder is a backstop).
|
|
194
|
+
// Resolved through the `onboarding` kernel port (BV1.R81); when the module
|
|
195
|
+
// is off there is no chore shelf, so this is a clean no-op.
|
|
196
|
+
const onboarding = seams.resolveOptional('onboarding');
|
|
197
|
+
if (onboarding && task && task.source === onboarding.SOURCE_TAG) {
|
|
198
|
+
try {
|
|
199
|
+
await onboarding.restockForClaim(task);
|
|
200
|
+
} catch (e) {
|
|
201
|
+
console.log('[gds] newcomer chore restock after claim failed (non-blocking):', e && e.message);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// V3.R51 (#270): claim.worktree_name is the SERVER-DECIDED name. If the
|
|
205
|
+
// requested name collided with another currently-active claim, the server
|
|
206
|
+
// silently disambiguated it (e.g. "foo" → "foo-2") and the claim still
|
|
207
|
+
// succeeded — so the caller must read claim.worktree_name back, not assume
|
|
208
|
+
// it got the name it asked for.
|
|
209
|
+
res.status(201).json({ claim, task, just_unlocked: justUnlocked ?? [], overlap_warning: overlapWarning ?? null });
|
|
210
|
+
} catch (err) {
|
|
211
|
+
if (err && err.code) {
|
|
212
|
+
const status =
|
|
213
|
+
err.code === 'TASK_NOT_FOUND' ? 404 :
|
|
214
|
+
err.code === 'TASK_NOT_READY' ? 409 :
|
|
215
|
+
err.code === 'TOUCHES_CONFLICT' ? 409 :
|
|
216
|
+
err.code === 'MODULE_CONFLICT' ? 409 :
|
|
217
|
+
err.code === 'DEPS_NOT_SHIPPED' ? 409 :
|
|
218
|
+
// task 1670 / ADR 0096: an unrewarded (0/NULL credits_reward) task can't
|
|
219
|
+
// be claimed — the claim-time backstop to the promote gate. Grandfathered
|
|
220
|
+
// tasks (already 'ready' at migration 177) are exempt and never reach here.
|
|
221
|
+
err.code === 'REWARD_REQUIRED' ? 409 :
|
|
222
|
+
err.code === 'ALREADY_CLAIMED' ? 409 :
|
|
223
|
+
err.code === 'BUILDER_INACTIVE' ? 403 :
|
|
224
|
+
// V3.R15 #239: rank_too_low_for_task is the canonical Xenos-gate code;
|
|
225
|
+
// XENOS_RESTRICTED is the pre-rename alias still honored by callers
|
|
226
|
+
// on older releases.
|
|
227
|
+
err.code === 'rank_too_low_for_task' ? 403 :
|
|
228
|
+
err.code === 'XENOS_RESTRICTED' ? 403 :
|
|
229
|
+
// V3.R82 #301: the inverse rank gate — task.requires_rank above the
|
|
230
|
+
// builder's. Same 403 semantics as the Xenos gate; the body carries
|
|
231
|
+
// { required, actual } so the CLI can render a clean message.
|
|
232
|
+
err.code === 'INSUFFICIENT_RANK' ? 403 :
|
|
233
|
+
500;
|
|
234
|
+
// V4.R14 (#952): a TASK_NOT_READY 409 names the way forward instead of
|
|
235
|
+
// leaving the caller to discover the promote route by spelunking (#506).
|
|
236
|
+
if (err.code === 'TASK_NOT_READY') {
|
|
237
|
+
err.hint = taskNotReadyHint(taskId, err.currentStatus);
|
|
238
|
+
}
|
|
239
|
+
return res.fail(err.code, status, { ...err });
|
|
240
|
+
}
|
|
241
|
+
console.error('[gds] POST /claims', err);
|
|
242
|
+
res.fail('claim_failed', { status: 500, message: 'internal error' });
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// Atomic multi-claim. Body: { task_ids: [n,n,n], worktree_name?: string }.
|
|
247
|
+
// All-or-nothing: if any single task fails (already claimed, not ready, or
|
|
248
|
+
// touches conflict with another active claim OR another task in the batch),
|
|
249
|
+
// the whole transaction rolls back and we return 409 with a structured
|
|
250
|
+
// failures[] enumerating every problem found in one pass.
|
|
251
|
+
// rank: any-builder — atomic multi-claim; same Xenos row-level filter applies.
|
|
252
|
+
// V3.R13 (#237): same newcomer gate as POST /claims — a fresh builder can't
|
|
253
|
+
// sneak around the "one claim at a time" rule by batching.
|
|
254
|
+
router.post('/claims/batch', auth.requireBuilder, gateNewcomerClaim, async (req, res) => {
|
|
255
|
+
if (validateOrRespond(req, res, {
|
|
256
|
+
task_ids: { required: true, type: 'array', maxItems: 20 },
|
|
257
|
+
worktree_name: { type: 'string', maxLength: LIMITS.WORKTREE_NAME },
|
|
258
|
+
// task 1795: mirrors POST /claims' bind_session (web claims): passing
|
|
259
|
+
// false stores EVERY row's session as NULL, matching how a
|
|
260
|
+
// session-unbound claim already works there.
|
|
261
|
+
// task 1802: omitting the flag (the real-CLI-session default) no longer
|
|
262
|
+
// binds every row — db.claimTasksBatch only binds the FIRST inserted
|
|
263
|
+
// claim to the caller's session and leaves the rest unbound, so a real
|
|
264
|
+
// session can batch-claim 2+ tasks without tripping
|
|
265
|
+
// uniq_active_claim_per_session (migration 180) on the 2nd+ INSERT. A
|
|
266
|
+
// single-task batch call is unaffected (first row IS the only row).
|
|
267
|
+
bind_session: { type: 'boolean' },
|
|
268
|
+
})) return;
|
|
269
|
+
const { task_ids: taskIds, worktree_name: worktreePrefix, bind_session: bindSession } = req.body || {};
|
|
270
|
+
if (taskIds.length === 0) {
|
|
271
|
+
return res.fail('task_ids_required', 400);
|
|
272
|
+
}
|
|
273
|
+
if (taskIds.length > 20) {
|
|
274
|
+
// Safety cap. The optimizer doesn't return more than a handful at a time,
|
|
275
|
+
// and unlimited batches let one slow transaction lock up the table.
|
|
276
|
+
return res.fail('batch_too_large', 400, { max: 20 });
|
|
277
|
+
}
|
|
278
|
+
if (!taskIds.every((id) => Number.isFinite(Number(id)))) {
|
|
279
|
+
return res.fail('task_ids_must_be_numbers', 400);
|
|
280
|
+
}
|
|
281
|
+
try {
|
|
282
|
+
const { claims } = await db.claimTasksBatch({
|
|
283
|
+
taskIds: taskIds.map(Number),
|
|
284
|
+
builderId: req.builder.id,
|
|
285
|
+
worktreePrefix: worktreePrefix ?? null,
|
|
286
|
+
creatorSessionId: resolveCreatorSessionId(bindSession, req.gdsSession?.session_id),
|
|
287
|
+
});
|
|
288
|
+
res.status(201).json({ claims });
|
|
289
|
+
} catch (err) {
|
|
290
|
+
if (err && err.code === 'BATCH_FAILED') {
|
|
291
|
+
return res.fail('batch_failed', 409, { failures: err.failures });
|
|
292
|
+
}
|
|
293
|
+
if (err && err.code === 'BATCH_EMPTY') {
|
|
294
|
+
return res.fail('task_ids_required', 400);
|
|
295
|
+
}
|
|
296
|
+
if (err && err.code === 'BATCH_DUPLICATE_IDS') {
|
|
297
|
+
return res.fail('duplicate_task_ids', 400);
|
|
298
|
+
}
|
|
299
|
+
if (err && err.code === 'BUILDER_INACTIVE') {
|
|
300
|
+
return res.fail('BUILDER_INACTIVE', 403);
|
|
301
|
+
}
|
|
302
|
+
console.error('[gds] POST /claims/batch', err);
|
|
303
|
+
res.fail('batch_claim_failed', { status: 500, message: 'internal error' });
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// Bulk release (task 1758) — the batch twin of resolve(outcome='abandoned').
|
|
308
|
+
// Body: { claim_ids: [n,n,n], force?: boolean }. NOT all-or-nothing: each
|
|
309
|
+
// claim_id is scoped to its own ownership/state, so one bad id fails only
|
|
310
|
+
// that item — see db.releaseClaimsBatch for why (no cross-claim invariant
|
|
311
|
+
// makes sense for a release the way touches/module conflicts do for a claim).
|
|
312
|
+
// rank: any-builder — scoped to the caller's own claims (NOT_YOUR_CLAIM per item).
|
|
313
|
+
router.post('/claims/batch/release', auth.requireBuilder, async (req, res) => {
|
|
314
|
+
if (validateOrRespond(req, res, {
|
|
315
|
+
claim_ids: { required: true, type: 'array', maxItems: 20 },
|
|
316
|
+
force: { type: 'boolean' },
|
|
317
|
+
})) return;
|
|
318
|
+
const { claim_ids: claimIds, force } = req.body || {};
|
|
319
|
+
if (claimIds.length === 0) {
|
|
320
|
+
return res.fail('claim_ids_required', 400);
|
|
321
|
+
}
|
|
322
|
+
if (claimIds.length > 20) {
|
|
323
|
+
return res.fail('batch_too_large', 400, { max: 20 });
|
|
324
|
+
}
|
|
325
|
+
if (!claimIds.every((id) => Number.isFinite(Number(id)))) {
|
|
326
|
+
return res.fail('claim_ids_must_be_numbers', 400);
|
|
327
|
+
}
|
|
328
|
+
try {
|
|
329
|
+
const { released, failures } = await db.releaseClaimsBatch({
|
|
330
|
+
claimIds: claimIds.map(Number),
|
|
331
|
+
builderId: req.builder.id,
|
|
332
|
+
resolverSessionId: req.gdsSession?.session_id ?? null,
|
|
333
|
+
force: force === true,
|
|
334
|
+
});
|
|
335
|
+
res.json({ released, failures });
|
|
336
|
+
} catch (err) {
|
|
337
|
+
if (err && err.code === 'BATCH_EMPTY') {
|
|
338
|
+
return res.fail('claim_ids_required', 400);
|
|
339
|
+
}
|
|
340
|
+
console.error('[gds] POST /claims/batch/release', err);
|
|
341
|
+
res.fail('batch_release_failed', { status: 500, message: 'internal error' });
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
// Dry-run validate (task 1758) — read-only twin of claimTasksBatch's
|
|
346
|
+
// pre-flight checks. Tells the caller which of an arbitrary task_id set are
|
|
347
|
+
// individually claimable right now AND which pairs would conflict if claimed
|
|
348
|
+
// together (touches/module overlap, incl. against other builders' active
|
|
349
|
+
// claims) — WITHOUT claiming anything. Powers the hall's multi-select
|
|
350
|
+
// toolbar greying out invalid actions before a real batch claim.
|
|
351
|
+
// Body: { task_ids: [n,n,n] }.
|
|
352
|
+
// rank: any-builder — a Xenos can validate too (to see WHY something's invalid).
|
|
353
|
+
router.post('/claims/batch/validate', auth.requireBuilder, async (req, res) => {
|
|
354
|
+
if (validateOrRespond(req, res, {
|
|
355
|
+
task_ids: { required: true, type: 'array', maxItems: 20 },
|
|
356
|
+
})) return;
|
|
357
|
+
const { task_ids: taskIds } = req.body || {};
|
|
358
|
+
if (taskIds.length === 0) {
|
|
359
|
+
return res.fail('task_ids_required', 400);
|
|
360
|
+
}
|
|
361
|
+
if (!taskIds.every((id) => Number.isFinite(Number(id)))) {
|
|
362
|
+
return res.fail('task_ids_must_be_numbers', 400);
|
|
363
|
+
}
|
|
364
|
+
try {
|
|
365
|
+
const result = await db.validateClaimBatch({
|
|
366
|
+
taskIds: taskIds.map(Number),
|
|
367
|
+
builderId: req.builder.id,
|
|
368
|
+
});
|
|
369
|
+
res.json(result);
|
|
370
|
+
} catch (err) {
|
|
371
|
+
if (err && err.code === 'BATCH_EMPTY') {
|
|
372
|
+
return res.fail('task_ids_required', 400);
|
|
373
|
+
}
|
|
374
|
+
console.error('[gds] POST /claims/batch/validate', err);
|
|
375
|
+
res.fail('batch_validate_failed', { status: 500, message: 'internal error' });
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
// rank: any-builder — resolve own claim (ship/abandon); ownership checked in
|
|
380
|
+
// db.resolveClaim (NOT_YOUR_CLAIM). Supervisor hot path (preserved per CRITICAL §4).
|
|
381
|
+
router.post('/claims/:id/resolve', auth.requireBuilder, async (req, res) => {
|
|
382
|
+
if (validateOrRespond(req, res, {
|
|
383
|
+
outcome: { required: true, type: 'string', enum: CLAIM_OUTCOMES },
|
|
384
|
+
notes_md: { type: 'string', maxLength: LIMITS.NOTES },
|
|
385
|
+
value_summary: { type: 'string', maxLength: LIMITS.VALUE_SUMMARY },
|
|
386
|
+
verification: { type: 'object' },
|
|
387
|
+
force: { type: 'boolean' },
|
|
388
|
+
// touches[] cleanup [7/8] (task 882): the real committed changed-files,
|
|
389
|
+
// used to backfill touches[] from reality on a successful ship (the
|
|
390
|
+
// planning-time touches[] is now optional).
|
|
391
|
+
committed_files: { type: 'array', maxItems: 5000, itemsType: 'string' },
|
|
392
|
+
// Task #1048 (ADR 0046 follow-up): the builder's sandbox self-approval
|
|
393
|
+
// record { stamp, url, method } when a staged game change was reviewed +
|
|
394
|
+
// approved. The server stamps `by`/`at` authoritatively in db.resolveClaim.
|
|
395
|
+
sandbox_review: { type: 'object' },
|
|
396
|
+
})) return;
|
|
397
|
+
if (!Number.isFinite(Number(req.params.id))) {
|
|
398
|
+
return res.fail('validation_failed', 400, [{ field: 'id', reason: 'wrong_type', expected: 'integer' }]);
|
|
399
|
+
}
|
|
400
|
+
const claimId = Number(req.params.id);
|
|
401
|
+
const {
|
|
402
|
+
outcome,
|
|
403
|
+
notes_md: notesMd,
|
|
404
|
+
value_summary: valueSummary,
|
|
405
|
+
verification, // { passed: bool, scanner_clean: bool, smoke_clean: bool, notes_md: string }
|
|
406
|
+
force,
|
|
407
|
+
committed_files: committedFiles,
|
|
408
|
+
sandbox_review: sandboxReview, // { stamp, url, method } — server stamps by/at
|
|
409
|
+
} = req.body || {};
|
|
410
|
+
try {
|
|
411
|
+
const result = await db.resolveClaim({
|
|
412
|
+
claimId,
|
|
413
|
+
builderId: req.builder.id,
|
|
414
|
+
outcome,
|
|
415
|
+
notesMd: notesMd ?? null,
|
|
416
|
+
valueSummary: valueSummary ?? null,
|
|
417
|
+
verification: verification ?? null,
|
|
418
|
+
resolverSessionId: req.gdsSession?.session_id ?? null,
|
|
419
|
+
force: force === true,
|
|
420
|
+
committedFiles: Array.isArray(committedFiles) ? committedFiles : null,
|
|
421
|
+
sandboxReview: sandboxReview && typeof sandboxReview === 'object' ? sandboxReview : null,
|
|
422
|
+
});
|
|
423
|
+
// Response shape (Phase 5):
|
|
424
|
+
// taskStatus 'completed' | 'confirmed' | 'ready'
|
|
425
|
+
// creditsAwarded number — non-zero only if status reached 'confirmed'
|
|
426
|
+
// advanceToMerge bool — CLI should chain into merge-mode if true
|
|
427
|
+
res.json({ ok: true, ...result, just_unlocked: result.justUnlocked ?? [] });
|
|
428
|
+
} catch (err) {
|
|
429
|
+
if (err && err.code) {
|
|
430
|
+
const status =
|
|
431
|
+
err.code === 'CLAIM_NOT_FOUND' ? 404 :
|
|
432
|
+
err.code === 'NOT_YOUR_CLAIM' ? 403 :
|
|
433
|
+
err.code === 'CLAIM_SESSION_MISMATCH' ? 403 :
|
|
434
|
+
err.code === 'ALREADY_RESOLVED' ? 409 :
|
|
435
|
+
500;
|
|
436
|
+
return res.fail(err.code, status, { ...err });
|
|
437
|
+
}
|
|
438
|
+
console.error('[gds] POST /claims/:id/resolve', err);
|
|
439
|
+
res.fail('resolve_failed', { status: 500, message: 'internal error' });
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
// POST /claims/:id/release-on-behalf — V3.R14 (#238).
|
|
444
|
+
//
|
|
445
|
+
// Archon-only escape hatch. The normal /claims/:id/resolve path only
|
|
446
|
+
// accepts the original claimant; this route lets the Archon release
|
|
447
|
+
// someone else's stuck claim (typically a stale one the sweeper has
|
|
448
|
+
// not picked up yet, or a deliberate intervention).
|
|
449
|
+
//
|
|
450
|
+
// Body: { reason: string }. The reason is required — every Archon
|
|
451
|
+
// intervention needs a paper trail. Capped at LIMITS.NOTES.
|
|
452
|
+
//
|
|
453
|
+
// The release sets outcome='abandoned' and returns the task to
|
|
454
|
+
// status='ready' (same as a normal abandon). No credits land. The
|
|
455
|
+
// session_logs row carries the original builder_id with notes_md
|
|
456
|
+
// tagged "[archon-release]" + the acting Archon's @login so an audit
|
|
457
|
+
// grep can find every third-party release.
|
|
458
|
+
router.post('/claims/:id/release-on-behalf',
|
|
459
|
+
auth.requireBuilder,
|
|
460
|
+
auth.requireRank('archon'),
|
|
461
|
+
async (req, res) => {
|
|
462
|
+
if (validateOrRespond(req, res, {
|
|
463
|
+
reason: { required: true, type: 'string', maxLength: LIMITS.NOTES },
|
|
464
|
+
})) return;
|
|
465
|
+
const claimId = parseId(req, res, { code: 'bad_claim_id', positiveInt: true });
|
|
466
|
+
if (claimId === null) return;
|
|
467
|
+
const reason = String(req.body.reason || '').trim();
|
|
468
|
+
if (!reason) {
|
|
469
|
+
// Empty-after-trim is rejected — the whole point of the
|
|
470
|
+
// endpoint is the paper trail.
|
|
471
|
+
return res.fail('validation_failed', 400, [{ field: 'reason', reason: 'empty' }]);
|
|
472
|
+
}
|
|
473
|
+
try {
|
|
474
|
+
const result = await db.releaseClaimOnBehalf({
|
|
475
|
+
claimId,
|
|
476
|
+
archonId: req.builder.id,
|
|
477
|
+
archonLogin: req.builder.github_login || req.builder.display_name || null,
|
|
478
|
+
reason,
|
|
479
|
+
});
|
|
480
|
+
res.json({ ok: true, ...result });
|
|
481
|
+
} catch (err) {
|
|
482
|
+
if (err && err.code === 'CLAIM_NOT_FOUND') {
|
|
483
|
+
return res.fail('claim_not_found', 404);
|
|
484
|
+
}
|
|
485
|
+
if (err && err.code === 'ALREADY_RESOLVED') {
|
|
486
|
+
return res.fail('already_resolved', 409);
|
|
487
|
+
}
|
|
488
|
+
if (err && err.code === 'BAD_CLAIM_ID') {
|
|
489
|
+
return res.fail('bad_claim_id', 400);
|
|
490
|
+
}
|
|
491
|
+
console.error('[gds] POST /claims/:id/release-on-behalf', err);
|
|
492
|
+
res.fail('release_on_behalf_failed', { status: 500, message: 'internal error' });
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
);
|
|
496
|
+
|
|
497
|
+
return router;
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
// Exported for unit testing (tests/claims_bind_session.mjs) and reuse.
|
|
501
|
+
module.exports.resolveCreatorSessionId = resolveCreatorSessionId;
|
|
502
|
+
// V4.R14 (#952): the TASK_NOT_READY 409 hint — exported so its wording is pinned.
|
|
503
|
+
module.exports.taskNotReadyHint = taskNotReadyHint;
|
|
504
|
+
// task 1642: the pure session-scoped one-active-claim decision — exported for
|
|
505
|
+
// tests/one_active_claim_per_session.mjs (DB-free) and reuse.
|
|
506
|
+
module.exports.shouldRefuseSessionClaim = shouldRefuseSessionClaim;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// src/bongos/routes/dependencies.js — the polymorphic dependency edge's HTTP surface
|
|
2
|
+
// (ADR 0086 §5, BV1.R62 / task 1516).
|
|
3
|
+
//
|
|
4
|
+
// One "blocked-until-done" edge over {task, goal, criterion}. The task->task subset
|
|
5
|
+
// keeps its historical API (POST/PUT/DELETE /tasks/:id/dependencies in tasks.js);
|
|
6
|
+
// THIS router creates/removes edges that involve a goal or criterion — the new
|
|
7
|
+
// cross-tier coordination contract. A dependency is a REFERENCE, not a grant: it
|
|
8
|
+
// never widens module scope, so cross-goal / cross-version edges are allowed. The
|
|
9
|
+
// claim gate (db.unsatisfiedDeps) and the auto-promotion triggers resolve them.
|
|
10
|
+
//
|
|
11
|
+
// rank: archon. Authoring a cross-tier dependency reshapes execution order across
|
|
12
|
+
// shared workspaces; it stays owner-gated (the same posture as the Archon-only task
|
|
13
|
+
// dependency mutations in tasks.js). route-rank-check.EXPECTED_RANKS pins it.
|
|
14
|
+
|
|
15
|
+
const express = require('express');
|
|
16
|
+
// Intra-module + the published doorway — a module never requires a core internal.
|
|
17
|
+
const api = require('../../../src/module-api');
|
|
18
|
+
const auth = api;
|
|
19
|
+
const db = require('../db');
|
|
20
|
+
|
|
21
|
+
const KINDS = ['task', 'goal', 'criterion'];
|
|
22
|
+
|
|
23
|
+
// Validate + coerce the 4-tuple edge body. Ids may arrive as JSON numbers or numeric
|
|
24
|
+
// strings (pg serializes bigint as a string). Returns { fromKind, fromId, toKind,
|
|
25
|
+
// toId } or null when it has already sent a 400.
|
|
26
|
+
function parseEdge(req, res) {
|
|
27
|
+
const fromKind = req.body.from_kind;
|
|
28
|
+
const toKind = req.body.to_kind;
|
|
29
|
+
if (!KINDS.includes(fromKind) || !KINDS.includes(toKind)) {
|
|
30
|
+
res.fail('bad_kind', 400, { valid: KINDS });
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const fromId = Number(req.body.from_id);
|
|
34
|
+
const toId = Number(req.body.to_id);
|
|
35
|
+
if (!Number.isInteger(fromId) || fromId <= 0 || !Number.isInteger(toId) || toId <= 0) {
|
|
36
|
+
res.fail('bad_id', { status: 400, message: 'from_id and to_id must be positive integers.' });
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return { fromKind, fromId, toKind, toId };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function mapDepError(err, res, tag) {
|
|
43
|
+
if (err && err.code === 'SELF_DEP') return res.fail('self_dep', 400);
|
|
44
|
+
if (err && err.code === 'BAD_KIND') return res.fail('bad_kind', 400, { valid: KINDS });
|
|
45
|
+
if (err && err.code === 'NODE_NOT_FOUND') return res.fail('node_not_found', 404);
|
|
46
|
+
if (err && err.code === 'CYCLE') return res.fail('cycle', 409, { path: err.path });
|
|
47
|
+
console.error(`[gds] ${tag}`, err);
|
|
48
|
+
return res.fail('dependency_op_failed', { status: 500, message: 'internal error' });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = function buildDependenciesRouter() {
|
|
52
|
+
const router = express.Router();
|
|
53
|
+
|
|
54
|
+
// POST /dependencies — create an edge "from is blocked until to is done".
|
|
55
|
+
// rank: archon.
|
|
56
|
+
router.post('/dependencies', auth.requireBuilder, auth.requireRank('archon'), async (req, res) => {
|
|
57
|
+
const edge = parseEdge(req, res);
|
|
58
|
+
if (!edge) return;
|
|
59
|
+
try {
|
|
60
|
+
const dependency = await db.addDependency(edge.fromKind, edge.fromId, edge.toKind, edge.toId);
|
|
61
|
+
return res.status(201).json({ ok: true, dependency });
|
|
62
|
+
} catch (err) {
|
|
63
|
+
return mapDepError(err, res, 'POST /dependencies');
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// DELETE /dependencies — remove an edge (body carries the 4-tuple).
|
|
68
|
+
// rank: archon.
|
|
69
|
+
router.delete('/dependencies', auth.requireBuilder, auth.requireRank('archon'), async (req, res) => {
|
|
70
|
+
const edge = parseEdge(req, res);
|
|
71
|
+
if (!edge) return;
|
|
72
|
+
try {
|
|
73
|
+
const removed = await db.removeDependency(edge.fromKind, edge.fromId, edge.toKind, edge.toId);
|
|
74
|
+
if (!removed) return res.fail('dependency_not_found', 404);
|
|
75
|
+
return res.json({ ok: true });
|
|
76
|
+
} catch (err) {
|
|
77
|
+
return mapDepError(err, res, 'DELETE /dependencies');
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
return router;
|
|
82
|
+
};
|