@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,97 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
// Carved into modules/economy/ (BV1.R77 / ADR 0093 §1-2): auth gates + request
|
|
3
|
+
// validators reach through the published doorway; the cost_log writer is an
|
|
4
|
+
// intra-module require — a module never requires a core internal.
|
|
5
|
+
const api = require('../../../src/module-api');
|
|
6
|
+
const cost = require('../cost');
|
|
7
|
+
const { validateOrRespond, LIMITS } = api;
|
|
8
|
+
|
|
9
|
+
const COST_CATEGORIES = ['api', 'compute', 'infra', 'domain', 'art', 'other'];
|
|
10
|
+
|
|
11
|
+
module.exports = function buildCostRouter() {
|
|
12
|
+
const router = express.Router();
|
|
13
|
+
|
|
14
|
+
// rank: any-builder — log cost on own claim (idempotent via source/source_ref).
|
|
15
|
+
router.post('/cost', api.requireBuilder, async (req, res) => {
|
|
16
|
+
if (validateOrRespond(req, res, {
|
|
17
|
+
task_id: { type: 'integer', min: 1 },
|
|
18
|
+
amount_usd: { required: true, type: 'number', min: 0, max: 1000000 },
|
|
19
|
+
// Don't enum-restrict category — the existing skills set categories that
|
|
20
|
+
// may legitimately drift; just cap the length. (CLAUDE.md mentions
|
|
21
|
+
// api|compute|infra|domain|art|other as the canonical set.)
|
|
22
|
+
category: { required: true, type: 'string', maxLength: 64, minLength: 1 },
|
|
23
|
+
description: { type: 'string', maxLength: LIMITS.NOTES },
|
|
24
|
+
source: { type: 'string', maxLength: LIMITS.SOURCE },
|
|
25
|
+
source_ref: { type: 'string', maxLength: LIMITS.SOURCE_REF },
|
|
26
|
+
recorded_at: { type: 'string', maxLength: 64 },
|
|
27
|
+
// System 1 / task 1344: optional per-tier USD split (cost_log columns
|
|
28
|
+
// added by migration 123). session-cost.js sends these so spend can be
|
|
29
|
+
// attributed by tier (cache_read is the marathon sink). Omitted → NULL.
|
|
30
|
+
fresh_input_usd: { type: 'number', min: 0, max: 1000000 },
|
|
31
|
+
cache_read_usd: { type: 'number', min: 0, max: 1000000 },
|
|
32
|
+
cache_write_usd: { type: 'number', min: 0, max: 1000000 },
|
|
33
|
+
output_usd: { type: 'number', min: 0, max: 1000000 },
|
|
34
|
+
// V3.R11 (#91): builder_id is optional. When absent we default to the
|
|
35
|
+
// authed builder (the right answer 99% of the time). When provided it
|
|
36
|
+
// must match the authed builder — we don't let one builder attribute
|
|
37
|
+
// spend to another. Archons could in theory be allowed to override
|
|
38
|
+
// (e.g. for backfill), but the only existing backfill path is
|
|
39
|
+
// scripts/gds/backfill-cost.js, which runs as Lars (archon) and reads
|
|
40
|
+
// the historical ledger that had no builder_id anyway. Keep the rule
|
|
41
|
+
// tight; relax later if/when a real cross-builder use case appears.
|
|
42
|
+
builder_id: { type: 'integer', min: 1 },
|
|
43
|
+
// task #385 / migration 181: which skill invocation incurred this cost.
|
|
44
|
+
skill_name: { type: 'string', maxLength: 64 },
|
|
45
|
+
})) return;
|
|
46
|
+
const { task_id: taskId, amount_usd: amountUsd, category, description, source, source_ref: sourceRef, recorded_at: recordedAt, builder_id: bodyBuilderId,
|
|
47
|
+
fresh_input_usd: freshInputUsd, cache_read_usd: cacheReadUsd, cache_write_usd: cacheWriteUsd, output_usd: outputUsd,
|
|
48
|
+
skill_name: skillName } = req.body || {};
|
|
49
|
+
const authedBuilderId = Number(req.builder?.id);
|
|
50
|
+
let builderId = authedBuilderId || null;
|
|
51
|
+
if (bodyBuilderId != null) {
|
|
52
|
+
const requested = Number(bodyBuilderId);
|
|
53
|
+
if (!Number.isFinite(requested) || requested <= 0) {
|
|
54
|
+
return res.fail('bad_builder_id', 400);
|
|
55
|
+
}
|
|
56
|
+
if (requested !== authedBuilderId) {
|
|
57
|
+
return res.fail('builder_id_mismatch', { status: 403, message: 'builder_id must match the authenticated builder' });
|
|
58
|
+
}
|
|
59
|
+
builderId = requested;
|
|
60
|
+
}
|
|
61
|
+
let recordedAtDate = null;
|
|
62
|
+
if (recordedAt) {
|
|
63
|
+
const parsed = new Date(recordedAt);
|
|
64
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
65
|
+
return res.fail('bad_recorded_at', 400);
|
|
66
|
+
}
|
|
67
|
+
recordedAtDate = parsed;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const out = await cost.logCost({
|
|
71
|
+
taskId: taskId ?? null,
|
|
72
|
+
amountUsd,
|
|
73
|
+
category,
|
|
74
|
+
description: description ?? null,
|
|
75
|
+
source: source ?? 'manual',
|
|
76
|
+
sourceRef: sourceRef ?? null,
|
|
77
|
+
recordedAt: recordedAtDate,
|
|
78
|
+
builderId,
|
|
79
|
+
freshInputUsd: freshInputUsd ?? null,
|
|
80
|
+
cacheReadUsd: cacheReadUsd ?? null,
|
|
81
|
+
cacheWriteUsd: cacheWriteUsd ?? null,
|
|
82
|
+
outputUsd: outputUsd ?? null,
|
|
83
|
+
skillName: skillName ?? null,
|
|
84
|
+
});
|
|
85
|
+
if (!out) {
|
|
86
|
+
// ON CONFLICT skipped: same (source, source_ref) already logged. Idempotent.
|
|
87
|
+
return res.status(200).json({ skipped: true, reason: 'duplicate_source_ref' });
|
|
88
|
+
}
|
|
89
|
+
res.status(201).json({ id: out.id, recorded_at: out.recorded_at });
|
|
90
|
+
} catch (err) {
|
|
91
|
+
console.error('[gds] POST /cost', err);
|
|
92
|
+
res.fail('cost_failed', { status: 500, message: 'internal error' });
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return router;
|
|
97
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
// Carved into modules/economy/ (BV1.R77 / ADR 0093 §1-2): the leaderboard query
|
|
3
|
+
// is an intra-module require — a module never requires a core internal. The
|
|
4
|
+
// pagination helpers reach through the published doorway.
|
|
5
|
+
const api = require('../../../src/module-api');
|
|
6
|
+
const credits = require('../credits');
|
|
7
|
+
|
|
8
|
+
module.exports = function buildLeaderboardRouter() {
|
|
9
|
+
const router = express.Router();
|
|
10
|
+
|
|
11
|
+
// rank: public — leaderboard mirrors the public /public/leaderboard surface;
|
|
12
|
+
// preserved unauthenticated to match current production behavior.
|
|
13
|
+
router.get('/leaderboard', async (req, res) => {
|
|
14
|
+
// task 1750: top 100 — the hall Leaderboard view pages through these, and the
|
|
15
|
+
// "#N on the leaderboard" standing stat needs ranks beyond the top 20.
|
|
16
|
+
// R14 (#2001 / ADR 0119): honor ?limit=&offset= via the shared helper; the
|
|
17
|
+
// default 100 preserves the prior ceiling. The list is small + SQL-LIMIT'd, so
|
|
18
|
+
// fetch offset+limit and slice; `page` is additive (readers of .leaderboard
|
|
19
|
+
// are unchanged).
|
|
20
|
+
const { limit, offset } = api.parsePagination(req, { defaultLimit: 100, maxLimit: 200 });
|
|
21
|
+
const rows = await credits.leaderboard(offset + limit);
|
|
22
|
+
res.json({ leaderboard: rows.slice(offset, offset + limit), page: api.pageMeta(limit, offset) });
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return router;
|
|
26
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// The economy module's kernel PORT registration (BV1.R77 / ADR 0093 §1-2).
|
|
4
|
+
//
|
|
5
|
+
// economy exposes its credit-allocation + gamification + cost/leaderboard READ
|
|
6
|
+
// surface as the `reward` kernel PORT. CORE files that must NOT import a module
|
|
7
|
+
// resolve it instead:
|
|
8
|
+
// • the LIFECYCLE (db.applyGrade/confirmTask/claimTask/
|
|
9
|
+
// upsertSessionRecordWithReward) — credit allocation + the claim/ship
|
|
10
|
+
// gamification hooks, each passing its tx `client` (transaction-participant);
|
|
11
|
+
// • the core read routes (routes/me.js, routes/public.js, routes/builders.js,
|
|
12
|
+
// routes/sessions.js) — cost rollups, the leaderboard, achievement getters,
|
|
13
|
+
// streak previews, and the budget setter.
|
|
14
|
+
// All reach economy WITHOUT importing it by resolving the `reward` kernel PORT
|
|
15
|
+
// this factory registers (ADR 0093 §2: keep the state machine whole, extract the
|
|
16
|
+
// capability behind a seam). The provider IS the economy module's reward surface.
|
|
17
|
+
//
|
|
18
|
+
// Why a route factory for a routeless capability: `mountModuleRoutes` (the loader)
|
|
19
|
+
// is the one boot hook that runs BOTH in the live server AND whenever a test
|
|
20
|
+
// rebuilds the GDS router — so registering here (not in a poller) is what keeps
|
|
21
|
+
// the port present for the route-building tests too. Registration is
|
|
22
|
+
// hasProvider-guarded so re-instantiation never trips the seam's single-provider
|
|
23
|
+
// duplicate guard. (Mirrors modules/grading/routes/grade.js.)
|
|
24
|
+
|
|
25
|
+
const express = require('express');
|
|
26
|
+
const api = require('../../../src/module-api');
|
|
27
|
+
const reward = require('../reward');
|
|
28
|
+
|
|
29
|
+
function registerSeams() {
|
|
30
|
+
if (!api.hasProvider('reward')) {
|
|
31
|
+
api.registerProvider('reward', reward);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = function buildRewardRouter() {
|
|
36
|
+
registerSeams();
|
|
37
|
+
// No HTTP surface — the reward capability is a pure kernel port. The empty
|
|
38
|
+
// router is only the loader's contributes.routes mount vehicle; returning a
|
|
39
|
+
// valid express.Router() keeps mountModuleRoutes' `router.use(sub)` happy
|
|
40
|
+
// without exposing any endpoint.
|
|
41
|
+
return express.Router();
|
|
42
|
+
};
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Streak math + anti-gaming guards (PMS-V2 #52, criterion 3).
|
|
4
|
+
//
|
|
5
|
+
// Definitions (locked in PMS-V2 planning, see limitations/pms-v2.md):
|
|
6
|
+
// - A "ship-day" = a local-builder-timezone calendar day in which the builder
|
|
7
|
+
// shipped >=1 qualifying task.
|
|
8
|
+
// - A "qualifying ship" requires:
|
|
9
|
+
// * claim.outcome = 'shipped' (builder declared done)
|
|
10
|
+
// * task.status IN ('confirmed','shipped') (verification passed; credits landed)
|
|
11
|
+
// * task.est_minutes >= 15 (anti-gaming floor)
|
|
12
|
+
// NOTE: cleanup/refactor tasks DO now count (V3.R93 #354). The original
|
|
13
|
+
// PMS-V2 rule excluded kind='cleanup', which mildly penalized the exact
|
|
14
|
+
// simplification work we want to reward. That exclusion was removed in both
|
|
15
|
+
// the SQL below and the wouldExtendStreak guard; the only anti-gaming floor
|
|
16
|
+
// that remains is est_minutes >= 15.
|
|
17
|
+
// - Cap: at most 5 qualifying ships per local-day count toward streak (so you
|
|
18
|
+
// can't pad a streak by shipping micro-tasks). Note: since one calendar day
|
|
19
|
+
// is one ship-day regardless of count, the 5-cap doesn't change ship-day
|
|
20
|
+
// identification — it's a guard that's surfaced honestly in the per-day
|
|
21
|
+
// counts the API returns (and that future "qualifying ships" features can
|
|
22
|
+
// use to throttle credit recognition).
|
|
23
|
+
// - Current streak = consecutive ship-days ending today (in the builder's
|
|
24
|
+
// timezone). If today is NOT a ship-day, current streak = 0. Strict.
|
|
25
|
+
// - Longest streak = the longest run of consecutive ship-days ever.
|
|
26
|
+
//
|
|
27
|
+
// SOURCE of ship events: claims (joined to tasks) — NOT session_logs. The
|
|
28
|
+
// session_logs row for a just-finishing ship is INSERTed AFTER evaluateAfterShip
|
|
29
|
+
// runs in resolveClaim, so it's invisible at evaluator time. The claim row,
|
|
30
|
+
// however, has already been UPDATEd to outcome='shipped' + released_at=now()
|
|
31
|
+
// and the task to status='confirmed' before the evaluator fires, so claims+tasks
|
|
32
|
+
// gives us a stable, in-transaction view.
|
|
33
|
+
//
|
|
34
|
+
// Caller contract:
|
|
35
|
+
// - Pass a `client` for in-transaction calls (achievements evaluator path).
|
|
36
|
+
// - Pass `pool` for out-of-transaction calls (HTTP /me/streak path).
|
|
37
|
+
// Either works — both have .query().
|
|
38
|
+
|
|
39
|
+
// Carved into modules/economy/ (BV1.R77 / ADR 0093 §1-2): reach the shared pool
|
|
40
|
+
// through the published doorway — a module never requires a core internal.
|
|
41
|
+
const { pool } = require('../../src/module-api');
|
|
42
|
+
|
|
43
|
+
// -------------------------------------------------------------------------
|
|
44
|
+
// Core query — pulls a builder's qualifying ship-days in their local TZ.
|
|
45
|
+
// Caps each calendar day at 5 ships (anti-gaming).
|
|
46
|
+
//
|
|
47
|
+
// Returns: { ship_days: [{ local_date: 'YYYY-MM-DD', count: int (1..5) }],
|
|
48
|
+
// timezone: 'America/...' }
|
|
49
|
+
// Sorted by local_date ASC.
|
|
50
|
+
// -------------------------------------------------------------------------
|
|
51
|
+
async function qualifyingShipDays(client, builderId) {
|
|
52
|
+
const sql = `
|
|
53
|
+
WITH builder_tz AS (
|
|
54
|
+
SELECT timezone FROM builders WHERE id = $1
|
|
55
|
+
),
|
|
56
|
+
qualifying AS (
|
|
57
|
+
SELECT c.released_at,
|
|
58
|
+
((c.released_at AT TIME ZONE (SELECT timezone FROM builder_tz))::date) AS local_date
|
|
59
|
+
FROM claims c
|
|
60
|
+
JOIN tasks t ON t.id = c.task_id
|
|
61
|
+
WHERE c.builder_id = $1
|
|
62
|
+
AND c.outcome = 'shipped'
|
|
63
|
+
AND c.released_at IS NOT NULL
|
|
64
|
+
AND t.status IN ('confirmed', 'shipped')
|
|
65
|
+
AND t.est_minutes >= 15
|
|
66
|
+
),
|
|
67
|
+
ranked AS (
|
|
68
|
+
SELECT local_date,
|
|
69
|
+
ROW_NUMBER() OVER (PARTITION BY local_date ORDER BY released_at) AS rn
|
|
70
|
+
FROM qualifying
|
|
71
|
+
),
|
|
72
|
+
capped AS (
|
|
73
|
+
SELECT local_date, COUNT(*)::int AS cnt
|
|
74
|
+
FROM ranked
|
|
75
|
+
WHERE rn <= 5
|
|
76
|
+
GROUP BY local_date
|
|
77
|
+
)
|
|
78
|
+
SELECT to_char(local_date, 'YYYY-MM-DD') AS local_date,
|
|
79
|
+
cnt,
|
|
80
|
+
(SELECT timezone FROM builder_tz) AS timezone
|
|
81
|
+
FROM capped
|
|
82
|
+
ORDER BY local_date
|
|
83
|
+
`;
|
|
84
|
+
const { rows } = await client.query(sql, [builderId]);
|
|
85
|
+
if (rows.length === 0) {
|
|
86
|
+
// We still want the builder's timezone for downstream "today" math.
|
|
87
|
+
const { rows: tzRows } = await client.query(
|
|
88
|
+
'SELECT timezone FROM builders WHERE id = $1',
|
|
89
|
+
[builderId]
|
|
90
|
+
);
|
|
91
|
+
return {
|
|
92
|
+
ship_days: [],
|
|
93
|
+
timezone: tzRows[0]?.timezone || 'America/New_York',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
ship_days: rows.map((r) => ({ local_date: r.local_date, count: Number(r.cnt) })),
|
|
98
|
+
timezone: rows[0].timezone,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// -------------------------------------------------------------------------
|
|
103
|
+
// "Today" in the builder's local timezone, formatted as 'YYYY-MM-DD'.
|
|
104
|
+
// Pulled from Postgres so the same clock the qualifying-ships query used
|
|
105
|
+
// is used here (no JS-vs-DB clock drift, no host-TZ surprises).
|
|
106
|
+
// -------------------------------------------------------------------------
|
|
107
|
+
async function todayInBuilderTz(client, builderId) {
|
|
108
|
+
const { rows } = await client.query(
|
|
109
|
+
`SELECT to_char((now() AT TIME ZONE timezone)::date, 'YYYY-MM-DD') AS today
|
|
110
|
+
FROM builders WHERE id = $1`,
|
|
111
|
+
[builderId]
|
|
112
|
+
);
|
|
113
|
+
return rows[0]?.today || null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// -------------------------------------------------------------------------
|
|
117
|
+
// Pure helpers (no DB) — walk a sorted ascending list of YYYY-MM-DD strings
|
|
118
|
+
// and compute current + longest streak relative to "today" string.
|
|
119
|
+
// -------------------------------------------------------------------------
|
|
120
|
+
function ymdToOrdinal(ymd) {
|
|
121
|
+
// 'YYYY-MM-DD' → integer day-number suitable for diffing.
|
|
122
|
+
// Using Date.UTC so DST has no effect (we're comparing whole local days).
|
|
123
|
+
const [y, m, d] = ymd.split('-').map(Number);
|
|
124
|
+
return Math.floor(Date.UTC(y, m - 1, d) / 86400000);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function computeRunsFromShipDays(shipDayStrs, todayStr) {
|
|
128
|
+
if (!shipDayStrs || shipDayStrs.length === 0) {
|
|
129
|
+
return { current_streak: 0, longest_streak: 0, last_ship_day: null };
|
|
130
|
+
}
|
|
131
|
+
const ords = shipDayStrs.map(ymdToOrdinal);
|
|
132
|
+
const todayOrd = todayStr ? ymdToOrdinal(todayStr) : null;
|
|
133
|
+
|
|
134
|
+
// Longest run: walk and count consecutive (diff==1) values.
|
|
135
|
+
let longest = 1;
|
|
136
|
+
let run = 1;
|
|
137
|
+
for (let i = 1; i < ords.length; i++) {
|
|
138
|
+
if (ords[i] === ords[i - 1] + 1) {
|
|
139
|
+
run++;
|
|
140
|
+
if (run > longest) longest = run;
|
|
141
|
+
} else if (ords[i] === ords[i - 1]) {
|
|
142
|
+
// duplicate — shouldn't happen given GROUP BY, but stay defensive
|
|
143
|
+
continue;
|
|
144
|
+
} else {
|
|
145
|
+
run = 1;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Current run: streak ending TODAY (strict). If today is not a ship-day,
|
|
150
|
+
// current_streak = 0.
|
|
151
|
+
let current = 0;
|
|
152
|
+
if (todayOrd !== null) {
|
|
153
|
+
const lastOrd = ords[ords.length - 1];
|
|
154
|
+
if (lastOrd === todayOrd) {
|
|
155
|
+
current = 1;
|
|
156
|
+
for (let i = ords.length - 2; i >= 0; i--) {
|
|
157
|
+
if (ords[i] === ords[i + 1] - 1) {
|
|
158
|
+
current++;
|
|
159
|
+
} else {
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
current_streak: current,
|
|
168
|
+
longest_streak: longest,
|
|
169
|
+
last_ship_day: shipDayStrs[shipDayStrs.length - 1],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// -------------------------------------------------------------------------
|
|
174
|
+
// Public: computeStreak(builderId, [client])
|
|
175
|
+
// -------------------------------------------------------------------------
|
|
176
|
+
async function computeStreak(builderId, client) {
|
|
177
|
+
const c = client || pool;
|
|
178
|
+
const [{ ship_days, timezone }, today] = await Promise.all([
|
|
179
|
+
qualifyingShipDays(c, builderId),
|
|
180
|
+
todayInBuilderTz(c, builderId),
|
|
181
|
+
]);
|
|
182
|
+
const dayStrs = ship_days.map((d) => d.local_date);
|
|
183
|
+
const runs = computeRunsFromShipDays(dayStrs, today);
|
|
184
|
+
// Find when the current run started (for UI display + 'streak began' hint)
|
|
185
|
+
let current_started_on = null;
|
|
186
|
+
if (runs.current_streak > 0) {
|
|
187
|
+
const lastOrd = ymdToOrdinal(today);
|
|
188
|
+
const startOrd = lastOrd - (runs.current_streak - 1);
|
|
189
|
+
const ms = startOrd * 86400000;
|
|
190
|
+
const dt = new Date(ms);
|
|
191
|
+
const y = dt.getUTCFullYear();
|
|
192
|
+
const m = String(dt.getUTCMonth() + 1).padStart(2, '0');
|
|
193
|
+
const d = String(dt.getUTCDate()).padStart(2, '0');
|
|
194
|
+
current_started_on = `${y}-${m}-${d}`;
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
current_streak: runs.current_streak,
|
|
198
|
+
longest_streak: runs.longest_streak,
|
|
199
|
+
last_ship_day: runs.last_ship_day,
|
|
200
|
+
current_started_on,
|
|
201
|
+
timezone,
|
|
202
|
+
today,
|
|
203
|
+
ship_day_counts: ship_days, // useful for debug / future UI
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// -------------------------------------------------------------------------
|
|
208
|
+
// Public: wouldExtendStreak(builderId, taskId, [client])
|
|
209
|
+
//
|
|
210
|
+
// Preview helper: "if this task were shipped right now (qualifying), what
|
|
211
|
+
// would the streak become?" Used by /me to render hints like
|
|
212
|
+
// "shipping #52 would extend your streak to 4 days".
|
|
213
|
+
//
|
|
214
|
+
// Returns: { current_streak, projected_streak, qualifies, reason? }
|
|
215
|
+
// qualifies = false when task doesn't meet est_minutes>=15. (As of V3.R93
|
|
216
|
+
// #354 kind='cleanup' is NO LONGER a disqualifier — cleanup/refactor ships
|
|
217
|
+
// count toward streaks like any other ship.)
|
|
218
|
+
// reason explains why (rendered by CLI).
|
|
219
|
+
// -------------------------------------------------------------------------
|
|
220
|
+
async function wouldExtendStreak(builderId, taskId, client) {
|
|
221
|
+
const c = client || pool;
|
|
222
|
+
const cur = await computeStreak(builderId, c);
|
|
223
|
+
|
|
224
|
+
const { rows: taskRows } = await c.query(
|
|
225
|
+
'SELECT id, kind, est_minutes FROM tasks WHERE id = $1',
|
|
226
|
+
[taskId]
|
|
227
|
+
);
|
|
228
|
+
const task = taskRows[0];
|
|
229
|
+
if (!task) {
|
|
230
|
+
return { current_streak: cur.current_streak, projected_streak: cur.current_streak,
|
|
231
|
+
qualifies: false, reason: 'task-not-found' };
|
|
232
|
+
}
|
|
233
|
+
if ((task.est_minutes ?? 0) < 15) {
|
|
234
|
+
return { current_streak: cur.current_streak, projected_streak: cur.current_streak,
|
|
235
|
+
qualifies: false, reason: 'est_minutes<15' };
|
|
236
|
+
}
|
|
237
|
+
// V3.R93 (#354): kind='cleanup' used to disqualify here. It no longer does —
|
|
238
|
+
// cleanup/refactor ships count toward streaks. The only remaining floor is
|
|
239
|
+
// est_minutes >= 15 above.
|
|
240
|
+
|
|
241
|
+
// Project: today becomes (or stays) a ship-day.
|
|
242
|
+
const todayOrd = ymdToOrdinal(cur.today);
|
|
243
|
+
const ords = cur.ship_day_counts.map((d) => ymdToOrdinal(d.local_date));
|
|
244
|
+
|
|
245
|
+
if (cur.current_streak > 0) {
|
|
246
|
+
// Already shipped today → today already counted. Streak doesn't change
|
|
247
|
+
// from another ship today (one calendar day = one ship-day).
|
|
248
|
+
return {
|
|
249
|
+
current_streak: cur.current_streak,
|
|
250
|
+
projected_streak: cur.current_streak,
|
|
251
|
+
qualifies: true,
|
|
252
|
+
reason: 'today-already-counted',
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// current_streak = 0 means today is NOT yet a ship-day. Shipping now adds today.
|
|
257
|
+
// Find run length ending at yesterday.
|
|
258
|
+
let runEndingYesterday = 0;
|
|
259
|
+
if (ords.length > 0) {
|
|
260
|
+
const lastOrd = ords[ords.length - 1];
|
|
261
|
+
if (lastOrd === todayOrd - 1) {
|
|
262
|
+
runEndingYesterday = 1;
|
|
263
|
+
for (let i = ords.length - 2; i >= 0; i--) {
|
|
264
|
+
if (ords[i] === ords[i + 1] - 1) runEndingYesterday++;
|
|
265
|
+
else break;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
current_streak: cur.current_streak,
|
|
271
|
+
projected_streak: runEndingYesterday + 1,
|
|
272
|
+
qualifies: true,
|
|
273
|
+
reason: runEndingYesterday > 0 ? 'extends-yesterday-run' : 'starts-new-run',
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
module.exports = {
|
|
278
|
+
computeStreak,
|
|
279
|
+
wouldExtendStreak,
|
|
280
|
+
// Exported for testing
|
|
281
|
+
qualifyingShipDays,
|
|
282
|
+
todayInBuilderTz,
|
|
283
|
+
ymdToOrdinal,
|
|
284
|
+
computeRunsFromShipDays,
|
|
285
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# `grading` module — the grade-a-diff adversarial panel + the `grade` kernel port
|
|
2
|
+
|
|
3
|
+
> The **second CORE-domain** carved into a module (BV1.R73, [ADR 0091](../../docs/adr/<redacted>.md) §1+§4) — after memory (R72). It is the carve that proves ADR 0091 §4's load-bearing pattern: **keep the lifecycle state machine whole, extract the capability it invokes behind a kernel seam.** The lifecycle no longer imports the grader directly; it resolves a `grade` PORT this module registers.
|
|
4
|
+
|
|
5
|
+
Owns the **quality gate**: the v4 adversarial worker panel (Narc / Quality / Hacker / Efficiency, unanimous-PASS), the deterministic pre-passes (route-rank + permission-path, run as panel inputs), and the scoring **rubric**. `default: true` in `module.json` — every instance grades its own ships, so it mounts unconditionally unless explicitly disabled.
|
|
6
|
+
|
|
7
|
+
## The boundary (the one rule)
|
|
8
|
+
|
|
9
|
+
This module reaches core **only** through the published doorway `../../src/module-api.js` (`coreVersion ^1.6.0` — it needs the R73 doorway additions: `routeRankCheck`, `permissionPathCheck`, `llmCache`). It must **never** `require()` a core internal directly, and never another module. Core, in turn, must never `require()` a file in here — it reaches grading only through the `grade` port (below). Both directions are enforced by the BV1.R44/R45 fitness checks; R70's `kernel-imports-no-domain` check keeps the kernel from reaching back in.
|
|
10
|
+
|
|
11
|
+
## The `grade` kernel PORT (ADR 0091 §4 — the headline of this carve)
|
|
12
|
+
|
|
13
|
+
- **Provides — port `grade`** → the grader module surface. Registered in `routes/grade.js`'s factory (the loader runs it at boot, and again whenever a test rebuilds the GDS router — `hasProvider`-guarded so re-instantiation never trips the single-provider duplicate guard).
|
|
14
|
+
- **Core consumes it WITHOUT importing this module:**
|
|
15
|
+
- `routes/tasks.js` (the LIFECYCLE ship path, `POST /tasks/:id/grade`) resolves it via `seams.resolveOptional('grade')` and calls `grade.validateAndScore(...)` then `grade.serverSideGuards(...)`. A grading-disabled instance gets a clean `503 grading_unavailable` instead of a thrown `resolve()`.
|
|
16
|
+
- `routes/public.js` (`GET /public/grades`) resolves it the same way and reads `grade.RUBRIC.{threshold,version}`, falling back to `null` when grading is off.
|
|
17
|
+
- This replaced the former `const grader = require('../grader')` core→domain import in both files — the edge ADR 0091 §4 set out to sever.
|
|
18
|
+
|
|
19
|
+
Why a route factory for a module with **no HTTP routes**: `mountModuleRoutes` is the only loader hook that runs both in the live server and when a test rebuilds the GDS router, so it's where the port registration belongs. The factory returns an empty `express.Router()` purely as the mount vehicle.
|
|
20
|
+
|
|
21
|
+
## Files
|
|
22
|
+
|
|
23
|
+
| File | What |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `grader.js` | the quality gate (~86 KB): v4 adversarial panel + `validateAndScore`/`serverSideGuards`/`gradeSubagent`/`RUBRIC`. The deterministic pre-passes reach `routeRankCheck`/`permissionPathCheck` through the doorway; `runSubagentCached` wraps spawns in the doorway's `llmCache`. |
|
|
26
|
+
| `grader-workers/` | the four worker modules (`narc`/`quality`/`hacker`/`efficiency`) + shared kit (`fence`, `worker-prompt`, `worker-verdict`, `rubric`, `extract-json`, `index`). All intra-module relative requires — unchanged by the move. |
|
|
27
|
+
| `grader-rubric.json` | the single-source scoring rubric (thresholds, per-worker config). Read by `grader.js` + `grader-workers/rubric.js` via `__dirname`-relative paths — survives the move. |
|
|
28
|
+
| `routes/grade.js` | registers the `grade` port (above); no HTTP endpoint. |
|
|
29
|
+
|
|
30
|
+
## NOT in this module (deliberately left in core)
|
|
31
|
+
|
|
32
|
+
- **`cascade-dispatch.js`** — stays in `src/bongos/`. It is dormant System 3 (model-tier dispatch, `OTB_AUTONOMY_ENABLED`-gated; nothing calls it but its mock unit test), and its real dependencies are core `task-classifier` (lifecycle) + `skill-prefs` (builder-settings), **not** the grader (the grader is an injected `runner`, never imported). Moving it would force two gratuitous doorway domain-leaks (`classifyTaskKind`, `skill-prefs.getForBuilder`) for capabilities grading never uses — the "ceremony with no boundary benefit" ADR 0091 §Alternatives rejects. It stays a core lib (scoped to `grading` in `module-scope-map.js`) until autonomy/dispatch is carved (tranche 2). The grading scope-map glob lists it as a core file, not part of this dir.
|
|
33
|
+
- **`scripts/gds/grade-smoke.js`** + the other grading-owned CLIs — a command travels with its domain but stays under `scripts/gds/` (the memory-carve precedent). They `require('../../modules/grading/grader')`.
|
|
34
|
+
- **`llm-cache.js`** — shared LLM-cost infra core also uses (`routes/llm-cache.js`, the cost scripts); it stays core and is exposed to this module on the doorway as `api.llmCache` (a tracked R70 leak).
|
|
35
|
+
|
|
36
|
+
## Tables
|
|
37
|
+
|
|
38
|
+
None owned. The grade-attempt rows (`grades`, `grade_attempts`, …) are written by core `db.applyGrade` on the lifecycle side; grading only computes the verdict the route then persists. No `modules/grading/migrations/` yet.
|
|
39
|
+
|
|
40
|
+
## Tests
|
|
41
|
+
|
|
42
|
+
`tests/grader.mjs`, `tests/grader_panel.mjs`, `tests/grader_prompt_fencing.mjs`, `tests/grade_server_authoritative.mjs`, `tests/grade_unavailable_display.mjs` import from `modules/grading/…`. `tests/cascade-dispatch.mjs` still imports `src/bongos/cascade-dispatch.js` (it stayed core). `scripts/gds/grade-smoke.js` is the live panel smoke.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// modules/grading/db.js — the grading module's db slice (ADR 0102).
|
|
2
|
+
//
|
|
3
|
+
// The grade-TREND read (`builderRollingAvgGrade`) carved from the core db.js
|
|
4
|
+
// residue so the published doorway (a KERNEL_FILE) stops importing `./gds/db` —
|
|
5
|
+
// the last tranche-2 kernel→domain leak (fitness Check 12 / ADR 0091 §1).
|
|
6
|
+
//
|
|
7
|
+
// It reads `task_grades` (grading domain). Two consumers reach it through the
|
|
8
|
+
// `grade.builderRollingAvgGrade` seam port: core me.js's profile aggregator and
|
|
9
|
+
// the sessions module's BFG scorer. Both degrade to a zero-grade shape when this
|
|
10
|
+
// module is off (a vanilla instance). Reaches `pool` through the doorway.
|
|
11
|
+
//
|
|
12
|
+
// The old core copy interpolated a shared `gradePassCount` SQL fragment (a
|
|
13
|
+
// documented twin with lifecycle/db.js); that one-liner is inlined here so this
|
|
14
|
+
// slice carries no cross-file fragment dependency.
|
|
15
|
+
|
|
16
|
+
'use strict';
|
|
17
|
+
|
|
18
|
+
const api = require('../../src/module-api');
|
|
19
|
+
const { pool } = api;
|
|
20
|
+
|
|
21
|
+
// Rolling grade stats for a builder over the last `days`: { n, avg_score, n_passed }.
|
|
22
|
+
// Windows by graded_at; `shipped_by` attributes the grade to the builder who did
|
|
23
|
+
// the work. Returns a zero row when the builder has no grades in the window.
|
|
24
|
+
async function builderRollingAvgGrade(builderId, days = 14) {
|
|
25
|
+
const { rows } = await pool.query(
|
|
26
|
+
`SELECT
|
|
27
|
+
COUNT(*)::int AS n,
|
|
28
|
+
COALESCE(AVG(g.score), 0)::numeric(3,1) AS avg_score,
|
|
29
|
+
COALESCE(SUM(CASE WHEN g.passed THEN 1 ELSE 0 END), 0)::int AS n_passed
|
|
30
|
+
FROM task_grades g
|
|
31
|
+
JOIN tasks t ON t.id = g.task_id
|
|
32
|
+
WHERE t.shipped_by = $1
|
|
33
|
+
AND g.graded_at >= now() - ($2 || ' days')::interval`,
|
|
34
|
+
[builderId, String(days)]
|
|
35
|
+
);
|
|
36
|
+
return rows[0] || { n: 0, avg_score: 0, n_passed: 0 };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = { builderRollingAvgGrade };
|