@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,260 @@
|
|
|
1
|
+
// src/bongos/llm-cache.js — System 5 (task 1359): content-addressed LLM result
|
|
2
|
+
// cache. Memoizes idempotent model runs at the shared spawn primitive
|
|
3
|
+
// (grader.runSubagent) so an identical (normalized-prompt, model, task_type,
|
|
4
|
+
// git-tree-sha) invocation over UNCHANGED inputs replays a stored result at zero
|
|
5
|
+
// new tokens. v1 is EXACT-MATCH (semantic match deferred — ADR, task 1360).
|
|
6
|
+
//
|
|
7
|
+
// Validity is bound to the git SHA of the embedded inputs (scope_sha): a stale
|
|
8
|
+
// answer is only ever returned when the inputs are provably unchanged. The
|
|
9
|
+
// per-task-type normalizer registry is the OTHER correctness surface — it strips
|
|
10
|
+
// only provably-volatile lines (timestamps, run-ids, the architect's `version=`
|
|
11
|
+
// echo) so two logically-identical prompts hash the same WITHOUT ever collapsing
|
|
12
|
+
// two different requests.
|
|
13
|
+
//
|
|
14
|
+
// The pure helpers (sha256, normalizers, computeCacheKey, makeCacheSpec,
|
|
15
|
+
// scopeShaFor) are unit-tested DB-free (tests/llm-cache.mjs). The lookup/store/
|
|
16
|
+
// withCache helpers touch Postgres and are best-effort: any DB error degrades to
|
|
17
|
+
// "cache miss / no store", never breaking the caller (a cache must never be able
|
|
18
|
+
// to take down the thing it accelerates).
|
|
19
|
+
|
|
20
|
+
'use strict';
|
|
21
|
+
|
|
22
|
+
const crypto = require('crypto');
|
|
23
|
+
const { execSync } = require('child_process');
|
|
24
|
+
const { pool } = require('./pool');
|
|
25
|
+
|
|
26
|
+
// --- transport (System 5 transport fix, task 1381) ---------------------------
|
|
27
|
+
// The cache DB lives on the droplet (peer-socket pool). Its consumers
|
|
28
|
+
// (architect-audit, onboarding-analyze) run as CLI/cron on BUILDER machines where
|
|
29
|
+
// the pool is unreachable — so before this, every cache op silently degraded to
|
|
30
|
+
// miss/no-store and the cache could never hit. Fix: keep the pool as the server
|
|
31
|
+
// fast path; fall back to the GDS API when the pool is unavailable. The core
|
|
32
|
+
// NEVER statically requires the CLI layer (scripts/gds/cli-lib.js) — that would
|
|
33
|
+
// drag session/fetch plumbing into the always-on server and cross the core↔host
|
|
34
|
+
// boundary the fitness gate guards. Instead the consumer (which already imports
|
|
35
|
+
// cli-lib) INJECTS apiCall via setApiFallback(). If it's never set, behaviour is
|
|
36
|
+
// exactly today's pool-only best-effort.
|
|
37
|
+
let _apiCall = null; // injected: (method, path, body, opts) => {ok,status,data}
|
|
38
|
+
let _poolReachable = null; // memoized SELECT-1 probe: `true` is sticky; false is never memoized (re-probe)
|
|
39
|
+
|
|
40
|
+
function setApiFallback(fn) { _apiCall = typeof fn === 'function' ? fn : null; }
|
|
41
|
+
function _resetTransportForTests() { _apiCall = null; _poolReachable = null; }
|
|
42
|
+
|
|
43
|
+
// Is the in-process pool usable? On the droplet → true (peer socket), memoized
|
|
44
|
+
// sticky. On a builder box → false (no DB) and we route through the injected
|
|
45
|
+
// apiCall. We deliberately do NOT memoize a `false` result (the critique's
|
|
46
|
+
// fix): a transient boot-time blip must never permanently disable the server
|
|
47
|
+
// cache — so a false just re-probes next call. The probe fails fast on a missing
|
|
48
|
+
// socket (ENOENT/ECONNREFUSED), not a long TCP timeout.
|
|
49
|
+
async function poolReachable() {
|
|
50
|
+
if (_poolReachable === true) return true;
|
|
51
|
+
try { await pool.query('SELECT 1'); _poolReachable = true; return true; }
|
|
52
|
+
catch (_) { return false; }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function sha256(s) {
|
|
56
|
+
return crypto.createHash('sha256').update(String(s == null ? '' : s), 'utf8').digest('hex');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Lines that are provably volatile between two otherwise-identical runs. Stripping
|
|
60
|
+
// them is what lets a re-run of an unchanged audit hash identically. Conservative
|
|
61
|
+
// by design — only patterns that cannot carry request meaning.
|
|
62
|
+
const VOLATILE_LINE = [
|
|
63
|
+
/\bversion\s*=\s*\S+/i, // the architect prompt's version= echo
|
|
64
|
+
/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}/, // ISO-ish timestamps
|
|
65
|
+
/\brun[_-]?id\b/i,
|
|
66
|
+
/\bgenerated[_ ]?at\b/i,
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
function stripVolatile(text) {
|
|
70
|
+
return String(text == null ? '' : text)
|
|
71
|
+
.split('\n')
|
|
72
|
+
.filter((l) => !VOLATILE_LINE.some((re) => re.test(l)))
|
|
73
|
+
.join('\n')
|
|
74
|
+
.trim();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Per-task-type normalizers. Default trims; the known idempotent producers strip
|
|
78
|
+
// volatile lines. Register more via registerNormalizer (kept open for new crons).
|
|
79
|
+
const NORMALIZERS = {
|
|
80
|
+
default: (p) => String(p == null ? '' : p).trim(),
|
|
81
|
+
'architect-audit': stripVolatile,
|
|
82
|
+
'onboarding-analyze': stripVolatile,
|
|
83
|
+
};
|
|
84
|
+
function registerNormalizer(taskType, fn) { NORMALIZERS[taskType] = fn; }
|
|
85
|
+
function normalize(taskType, prompt) {
|
|
86
|
+
const fn = NORMALIZERS[taskType] || NORMALIZERS.default;
|
|
87
|
+
return fn(prompt);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// The content address: sha256 over the normalized prompt + the dimensions that
|
|
91
|
+
// change correctness (model, task_type, the input git-tree sha). NUL-joined so
|
|
92
|
+
// no field can bleed into the next.
|
|
93
|
+
function computeCacheKey({ prompt, model, task_type, scope_sha } = {}) {
|
|
94
|
+
const normalized = normalize(task_type, prompt);
|
|
95
|
+
return sha256([normalized, model || '', task_type || '', scope_sha || ''].join('\u0000'));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// A complete cache spec the caller hands to runSubagentCached / withCache.
|
|
99
|
+
function makeCacheSpec({ prompt, model, task_type, scope_sha, owner_builder_id = null, ttl_ms = null } = {}) {
|
|
100
|
+
return {
|
|
101
|
+
key: computeCacheKey({ prompt, model, task_type, scope_sha }),
|
|
102
|
+
prompt_hash: sha256(normalize(task_type, prompt)),
|
|
103
|
+
model: model || null,
|
|
104
|
+
task_type: task_type || null,
|
|
105
|
+
scope_sha: scope_sha || null,
|
|
106
|
+
owner_builder_id: owner_builder_id == null ? null : Number(owner_builder_id),
|
|
107
|
+
ttl_ms: ttl_ms == null ? null : Number(ttl_ms),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// git tree/blob SHA of the embedded inputs — the invalidation key. A directory
|
|
112
|
+
// path resolves to its tree SHA (changes iff any file under it changes); a file
|
|
113
|
+
// to its blob SHA. runner injectable for tests. A path absent from HEAD → MISSING
|
|
114
|
+
// (so an unborn/typo'd path never silently collides with a real one).
|
|
115
|
+
function scopeShaFor(paths, { runner, cwd } = {}) {
|
|
116
|
+
const run = runner || ((cmd) => execSync(cmd, { encoding: 'utf8', cwd: cwd || process.cwd() }).trim());
|
|
117
|
+
const parts = [];
|
|
118
|
+
for (const p of paths || []) {
|
|
119
|
+
let sha = 'MISSING';
|
|
120
|
+
try { sha = run(`git rev-parse HEAD:${p}`) || 'MISSING'; } catch (_) { sha = 'MISSING'; }
|
|
121
|
+
parts.push(`${p}:${sha}`);
|
|
122
|
+
}
|
|
123
|
+
return sha256(parts.join('\n'));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// --- DB (best-effort; a cache error degrades to miss/no-store) ---------------
|
|
127
|
+
|
|
128
|
+
// Look up a live (unexpired) entry by key. On a hit, atomically bump hit_count +
|
|
129
|
+
// last_hit_at and return the stored result. Returns null on miss or any error.
|
|
130
|
+
async function lookup(cacheKey, { tokensSavedEst = 0 } = {}) {
|
|
131
|
+
if (!cacheKey) return null;
|
|
132
|
+
const est = Math.max(0, Number(tokensSavedEst) || 0);
|
|
133
|
+
// Pool fast path (server).
|
|
134
|
+
if (await poolReachable()) {
|
|
135
|
+
try {
|
|
136
|
+
const { rows } = await pool.query(
|
|
137
|
+
`UPDATE llm_cache
|
|
138
|
+
SET hit_count = hit_count + 1,
|
|
139
|
+
last_hit_at = now(),
|
|
140
|
+
tokens_saved_est = tokens_saved_est + $2
|
|
141
|
+
WHERE cache_key = $1
|
|
142
|
+
AND (expires_at IS NULL OR expires_at > now())
|
|
143
|
+
RETURNING result_stdout, result_cost_usd, hit_count, task_type, scope_sha, model`,
|
|
144
|
+
[cacheKey, est]
|
|
145
|
+
);
|
|
146
|
+
return rows[0] || null;
|
|
147
|
+
} catch (_) { /* fall through to API if injected, else miss */ }
|
|
148
|
+
}
|
|
149
|
+
// API fallback (builder machine). Best-effort: any error → miss. allowUnauthenticated
|
|
150
|
+
// so an expired session degrades to a miss instead of process.exit — a cache
|
|
151
|
+
// must never take down the thing it accelerates.
|
|
152
|
+
if (_apiCall) {
|
|
153
|
+
try {
|
|
154
|
+
const r = await _apiCall('POST', '/api/gds/llm-cache/lookup',
|
|
155
|
+
{ cache_key: cacheKey, tokens_saved_est: est }, { allowUnauthenticated: true });
|
|
156
|
+
if (r && r.ok && r.data && r.data.hit) return r.data.result || null;
|
|
157
|
+
} catch (_) { /* network/auth error → miss */ }
|
|
158
|
+
}
|
|
159
|
+
return null; // missing table / unreachable / no fallback → treat as a miss
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Store a freshly-produced result. Upsert so a re-store refreshes. Best-effort.
|
|
163
|
+
async function store(spec, { resultStdout, resultCostUsd = 0 } = {}) {
|
|
164
|
+
if (!spec || !spec.key || resultStdout == null) return false;
|
|
165
|
+
// Pool fast path (server).
|
|
166
|
+
if (await poolReachable()) {
|
|
167
|
+
const expiresExpr = spec.ttl_ms ? `now() + ($9::bigint * interval '1 millisecond')` : 'NULL';
|
|
168
|
+
try {
|
|
169
|
+
await pool.query(
|
|
170
|
+
`INSERT INTO llm_cache
|
|
171
|
+
(cache_key, prompt_hash, model, task_type, scope_sha, result_stdout, result_cost_usd, owner_builder_id, expires_at)
|
|
172
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, ${expiresExpr})
|
|
173
|
+
ON CONFLICT (cache_key) DO UPDATE
|
|
174
|
+
SET result_stdout = EXCLUDED.result_stdout,
|
|
175
|
+
result_cost_usd = EXCLUDED.result_cost_usd,
|
|
176
|
+
last_hit_at = now()`,
|
|
177
|
+
spec.ttl_ms
|
|
178
|
+
? [spec.key, spec.prompt_hash, spec.model, spec.task_type, spec.scope_sha, resultStdout, Number(resultCostUsd) || 0, spec.owner_builder_id, spec.ttl_ms]
|
|
179
|
+
: [spec.key, spec.prompt_hash, spec.model, spec.task_type, spec.scope_sha, resultStdout, Number(resultCostUsd) || 0, spec.owner_builder_id]
|
|
180
|
+
);
|
|
181
|
+
return true;
|
|
182
|
+
} catch (_) { /* fall through to API if injected, else no-store */ }
|
|
183
|
+
}
|
|
184
|
+
// API fallback (builder machine). The route re-validates the spec + clamps the
|
|
185
|
+
// cost server-side; best-effort: any error → no-store (never throws).
|
|
186
|
+
if (_apiCall) {
|
|
187
|
+
try {
|
|
188
|
+
const r = await _apiCall('POST', '/api/gds/llm-cache/store',
|
|
189
|
+
{ spec, result_stdout: resultStdout, result_cost_usd: Number(resultCostUsd) || 0 },
|
|
190
|
+
{ allowUnauthenticated: true });
|
|
191
|
+
return !!(r && r.ok && r.data && r.data.stored);
|
|
192
|
+
} catch (_) { return false; }
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Record a hit as a SAVING in System 1's counterfactual ledger (cost_baseline,
|
|
198
|
+
// ADR 0075): baseline_usd = what the run WOULD have cost, amount_usd = 0 (the hit
|
|
199
|
+
// was free). source_ref is per-hit-unique so each replay counts once. Best-effort.
|
|
200
|
+
async function recordSaving(spec, { resultCostUsd = 0, hitCount = 0 } = {}) {
|
|
201
|
+
const baseline = Number(resultCostUsd) || 0;
|
|
202
|
+
if (!spec || !spec.key || baseline <= 0) return; // nothing priced → nothing to claim
|
|
203
|
+
// Pool-ONLY by design — deliberately NO API fallback. The saving lands in the
|
|
204
|
+
// PUBLIC cost ledger (cost_baseline → /public/cost-summary), so per the
|
|
205
|
+
// migration-124 contract it must be a server-side-priced figure, never a
|
|
206
|
+
// client-supplied dollar amount. Off-server (builder machine) this no-ops: a
|
|
207
|
+
// System-5 hit is still RECORDED (hit_count bumped in lookup), but its $ saving
|
|
208
|
+
// is not booked until a follow-up forwards the subagent's token usage so /store
|
|
209
|
+
// can re-price it server-side via priceUsage (task 1381 notes → follow-up).
|
|
210
|
+
// Booking nothing here is correct; booking a client figure would break the
|
|
211
|
+
// contract. The poolReachable guard also avoids a failed-query log on builders.
|
|
212
|
+
if (!(await poolReachable())) return;
|
|
213
|
+
try {
|
|
214
|
+
await pool.query(
|
|
215
|
+
`INSERT INTO cost_baseline (system, baseline_usd, amount_usd, source_ref, description)
|
|
216
|
+
VALUES ('system5:llm-cache', $1, 0, $2, $3)
|
|
217
|
+
ON CONFLICT (system, source_ref) WHERE source_ref IS NOT NULL DO NOTHING`,
|
|
218
|
+
[baseline, `${spec.key}:${hitCount}`, `llm-cache hit (${spec.task_type || 'unknown'})`]
|
|
219
|
+
);
|
|
220
|
+
} catch (_) { /* cost_baseline absent (pre-deploy) or transient → skip */ }
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Orchestrator: hit → return cached at $0 (+ record the saving); miss → run the
|
|
224
|
+
// producer, store on a clean result, return it. `producer` resolves to a
|
|
225
|
+
// runSubagent-shaped object { stdout, exit_code, cost_usd }.
|
|
226
|
+
async function withCache(spec, producer) {
|
|
227
|
+
if (!spec || !spec.key) return { ...(await producer()), cached: false };
|
|
228
|
+
const hit = await lookup(spec.key);
|
|
229
|
+
if (hit) {
|
|
230
|
+
await recordSaving(spec, { resultCostUsd: Number(hit.result_cost_usd) || 0, hitCount: hit.hit_count });
|
|
231
|
+
return { stdout: hit.result_stdout, stderr: '', run_ms: 0, exit_code: 0, cost_usd: 0, cached: true };
|
|
232
|
+
}
|
|
233
|
+
const res = await producer();
|
|
234
|
+
// Only ever cache a clean, completed run — never a timeout or a non-zero exit.
|
|
235
|
+
if (res && res.exit_code === 0 && res.stdout != null) {
|
|
236
|
+
await store(spec, { resultStdout: res.stdout, resultCostUsd: Number(res.cost_usd) || 0 });
|
|
237
|
+
}
|
|
238
|
+
return { ...res, cached: false };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
module.exports = {
|
|
242
|
+
// pure (unit-tested)
|
|
243
|
+
sha256,
|
|
244
|
+
stripVolatile,
|
|
245
|
+
NORMALIZERS,
|
|
246
|
+
registerNormalizer,
|
|
247
|
+
normalize,
|
|
248
|
+
computeCacheKey,
|
|
249
|
+
makeCacheSpec,
|
|
250
|
+
scopeShaFor,
|
|
251
|
+
// transport (System 5 transport fix, task 1381)
|
|
252
|
+
setApiFallback,
|
|
253
|
+
poolReachable,
|
|
254
|
+
_resetTransportForTests,
|
|
255
|
+
// DB (best-effort)
|
|
256
|
+
lookup,
|
|
257
|
+
store,
|
|
258
|
+
recordSaving,
|
|
259
|
+
withCache,
|
|
260
|
+
};
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
// src/bongos/llm-pricing.js — ADR 0028 path 2 (#560).
|
|
2
|
+
//
|
|
3
|
+
// Prices a Claude transcript `usage` block into USD. The interactive builder
|
|
4
|
+
// session is not a `claude -p` subprocess, so (unlike the grader path, #486)
|
|
5
|
+
// there is no `total_cost_usd` envelope — the session transcript JSONL carries
|
|
6
|
+
// only TOKEN counts. This module is the small, auditable table + pure function
|
|
7
|
+
// that turns those tokens into dollars.
|
|
8
|
+
//
|
|
9
|
+
// Pure: no I/O, no Date.now(), no network. Imported by scripts/gds/session-cost.js
|
|
10
|
+
// (and available as the grader's envelope-absent fallback). Unit-tested in
|
|
11
|
+
// tests/llm-pricing.mjs.
|
|
12
|
+
//
|
|
13
|
+
// PRICES are USD per MILLION tokens (Anthropic public list price). When prices
|
|
14
|
+
// change this table is the single edit point; a price change is `decision`-worthy
|
|
15
|
+
// and gets its own task. Cache multipliers follow Anthropic's published model:
|
|
16
|
+
// - cache WRITE 5-minute TTL = 1.25× base input
|
|
17
|
+
// - cache WRITE 1-hour TTL = 2.00× base input
|
|
18
|
+
// - cache READ = 0.10× base input
|
|
19
|
+
//
|
|
20
|
+
// Pricing is FLAT across the full context window — current Opus 4.8 and Sonnet
|
|
21
|
+
// 4.6 provide the 1M window at standard pricing with NO long-context (>200K)
|
|
22
|
+
// premium (verified against platform.claude.com models overview, 2026-06-20).
|
|
23
|
+
// So there is no per-tier "1M premium" table to maintain; do not add one unless
|
|
24
|
+
// Anthropic introduces a long-context surcharge.
|
|
25
|
+
//
|
|
26
|
+
// VERIFIED 2026-06-20 against the live Anthropic models/pricing page (GDS-V4
|
|
27
|
+
// task 1343): the table below had drifted to Opus 4.1-era pricing ($15/$75),
|
|
28
|
+
// which 3× over-priced the platform's Opus 4.8 interactive sessions and inflated
|
|
29
|
+
// the recorded cost_log ~3× on the opus-dominated spend. Corrected to the
|
|
30
|
+
// current per-model list rates:
|
|
31
|
+
// - opus = Claude Opus 4.8 / 4.7 ($5 in / $25 out) [was $15/$75]
|
|
32
|
+
// - sonnet = Claude Sonnet 4.6 ($3 in / $15 out) [unchanged — was correct]
|
|
33
|
+
// - haiku = Claude Haiku 4.5 ($1 in / $5 out) [was $0.8/$4 = Haiku 3.5]
|
|
34
|
+
// Family-based pricing assumes the CURRENT model in each family (what this
|
|
35
|
+
// instance runs). A historical id like claude-opus-4-1 ($15/$75) would be
|
|
36
|
+
// mis-priced low here — acceptable: the platform only runs 4.x-current models.
|
|
37
|
+
const PRICES = {
|
|
38
|
+
// family : { input, output, cache_write_5m, cache_write_1h, cache_read } (USD / 1e6 tokens)
|
|
39
|
+
opus: { input: 5, output: 25, cache_write_5m: 6.25, cache_write_1h: 10, cache_read: 0.5 },
|
|
40
|
+
sonnet: { input: 3, output: 15, cache_write_5m: 3.75, cache_write_1h: 6, cache_read: 0.3 },
|
|
41
|
+
haiku: { input: 1, output: 5, cache_write_5m: 1.25, cache_write_1h: 2, cache_read: 0.1 },
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// Resolve a model id (e.g. 'claude-opus-4-8', 'claude-sonnet-4-6',
|
|
45
|
+
// 'claude-haiku-4-5') to a price family by substring — mirrors grader.js's
|
|
46
|
+
// family-token convention (all live Claude ids contain one of these three).
|
|
47
|
+
// Unknown → null (caller decides: we conservatively price at the opus rate AND
|
|
48
|
+
// flag it, so an unpriced model is loud, never silently $0).
|
|
49
|
+
function familyFor(model) {
|
|
50
|
+
const m = String(model || '').toLowerCase();
|
|
51
|
+
if (m.includes('opus')) return 'opus';
|
|
52
|
+
if (m.includes('sonnet')) return 'sonnet';
|
|
53
|
+
if (m.includes('haiku')) return 'haiku';
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Price one usage block.
|
|
59
|
+
* @param {string} model - message.model from a transcript line.
|
|
60
|
+
* @param {object} usage - message.usage: { input_tokens, output_tokens,
|
|
61
|
+
* cache_read_input_tokens, cache_creation_input_tokens,
|
|
62
|
+
* cache_creation?: { ephemeral_5m_input_tokens, ephemeral_1h_input_tokens } }
|
|
63
|
+
* @returns {{ usd:number, family:string, priced_as:string, unknown_model:boolean,
|
|
64
|
+
* components:{ input, output, cache_read, cache_write_5m, cache_write_1h } }}
|
|
65
|
+
* where each component is { tokens:number, usd:number } — the per-tier split the
|
|
66
|
+
* cost ledger persists (GDS-V4 task 1343/1344) so spend can be broken down by
|
|
67
|
+
* tier (cache_read is the dominant marathon-session cost). `usd` is their sum.
|
|
68
|
+
*/
|
|
69
|
+
function priceUsage(model, usage) {
|
|
70
|
+
const u = usage || {};
|
|
71
|
+
const fam = familyFor(model);
|
|
72
|
+
const unknownModel = fam === null;
|
|
73
|
+
const priceFamily = fam || 'opus'; // conservative default for an unrecognized model
|
|
74
|
+
const p = PRICES[priceFamily];
|
|
75
|
+
|
|
76
|
+
const input = Number(u.input_tokens) || 0; // uncached input
|
|
77
|
+
const output = Number(u.output_tokens) || 0;
|
|
78
|
+
const cacheRead = Number(u.cache_read_input_tokens) || 0;
|
|
79
|
+
const cacheCreateTotal = Number(u.cache_creation_input_tokens) || 0;
|
|
80
|
+
|
|
81
|
+
// Prefer the 5m/1h breakdown when present; otherwise treat the whole
|
|
82
|
+
// cache-creation lump at the 5m rate (the common default TTL).
|
|
83
|
+
const br = u.cache_creation || {};
|
|
84
|
+
const has5 = u.cache_creation && u.cache_creation.ephemeral_5m_input_tokens != null;
|
|
85
|
+
const has1h = u.cache_creation && u.cache_creation.ephemeral_1h_input_tokens != null;
|
|
86
|
+
let write5m, write1h;
|
|
87
|
+
if (has5 || has1h) {
|
|
88
|
+
write5m = Number(br.ephemeral_5m_input_tokens) || 0;
|
|
89
|
+
write1h = Number(br.ephemeral_1h_input_tokens) || 0;
|
|
90
|
+
// The breakdown may not enumerate every creation token. cache_creation_input_tokens
|
|
91
|
+
// is the authoritative total — fold any remainder beyond the 5m+1h split into
|
|
92
|
+
// the 5m tier so those tokens are still priced rather than silently dropped.
|
|
93
|
+
const remainder = cacheCreateTotal - write5m - write1h;
|
|
94
|
+
if (remainder > 0) write5m += remainder;
|
|
95
|
+
} else {
|
|
96
|
+
write5m = cacheCreateTotal; // no breakdown → price the lump as 5m
|
|
97
|
+
write1h = 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Per-tier component split (tokens + usd). The cost ledger persists these so a
|
|
101
|
+
// marathon session's spend can be attributed to the tier it actually came from
|
|
102
|
+
// (overwhelmingly cache_read — a large context re-read every turn for hours).
|
|
103
|
+
const components = {
|
|
104
|
+
input: { tokens: input, usd: (input * p.input) / 1e6 },
|
|
105
|
+
output: { tokens: output, usd: (output * p.output) / 1e6 },
|
|
106
|
+
cache_read: { tokens: cacheRead, usd: (cacheRead * p.cache_read) / 1e6 },
|
|
107
|
+
cache_write_5m: { tokens: write5m, usd: (write5m * p.cache_write_5m) / 1e6 },
|
|
108
|
+
cache_write_1h: { tokens: write1h, usd: (write1h * p.cache_write_1h) / 1e6 },
|
|
109
|
+
};
|
|
110
|
+
const usd = components.input.usd + components.output.usd + components.cache_read.usd
|
|
111
|
+
+ components.cache_write_5m.usd + components.cache_write_1h.usd;
|
|
112
|
+
|
|
113
|
+
return { usd, family: priceFamily, priced_as: priceFamily, unknown_model: unknownModel, components };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Canonicalize a raw transcript model id into a stable grouping key so a session
|
|
117
|
+
// emitting both 'claude-opus-4-8' and 'claude-opus-4-8[1m]' (or a '-fast' /
|
|
118
|
+
// date-suffixed variant) collapses to ONE breakdown label. Pricing is family-
|
|
119
|
+
// based (familyFor matches by substring), so the canonical id is only a tidy
|
|
120
|
+
// label — the priced total is identical either way. Strips a trailing [..] tag,
|
|
121
|
+
// a -fast suffix, and an 8-digit date suffix.
|
|
122
|
+
function canonicalizeModelId(model) {
|
|
123
|
+
let s = String(model || '').trim();
|
|
124
|
+
s = s.replace(/\[[^\]]*\]\s*$/, ''); // drop trailing [1m] etc.
|
|
125
|
+
s = s.replace(/-fast$/i, ''); // drop -fast
|
|
126
|
+
s = s.replace(/-\d{8}$/, ''); // drop -YYYYMMDD date suffix
|
|
127
|
+
return s;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Price a per-model token-usage map into ONE total USD figure, server-side.
|
|
132
|
+
* This is the cost-plus reward's "true_cost_usd" source (task 1005, ADR 0054):
|
|
133
|
+
* it NEVER trusts a client dollar figure — it prices token counts via the
|
|
134
|
+
* locked PRICES table here.
|
|
135
|
+
*
|
|
136
|
+
* @param {Object<string, {input?:number,output?:number,cache_read?:number,cache_creation?:number}>} modelUsage
|
|
137
|
+
* keyed by model id (raw or canonical). Field names are the session_records
|
|
138
|
+
* model_usage shape (NOT the transcript *_input_tokens shape).
|
|
139
|
+
* @returns {{ true_cost_usd:number, per_model:Array, unknown_models:string[] }}
|
|
140
|
+
* true_cost_usd rounded to 4 decimals (matches session-cost.js convention).
|
|
141
|
+
*/
|
|
142
|
+
function priceModelUsage(modelUsage) {
|
|
143
|
+
let usd = 0;
|
|
144
|
+
const perModel = [];
|
|
145
|
+
const unknown = [];
|
|
146
|
+
for (const [rawId, u] of Object.entries(modelUsage || {})) {
|
|
147
|
+
const usage = u || {};
|
|
148
|
+
// Map the model_usage field names → priceUsage's transcript field names.
|
|
149
|
+
// cache_creation here is a plain NUMBER (a lump), so we pass it as
|
|
150
|
+
// cache_creation_input_tokens (priced at the 5m rate) and never set the
|
|
151
|
+
// cache_creation breakdown object.
|
|
152
|
+
const priced = priceUsage(rawId, {
|
|
153
|
+
input_tokens: Number(usage.input) || 0,
|
|
154
|
+
output_tokens: Number(usage.output) || 0,
|
|
155
|
+
cache_read_input_tokens: Number(usage.cache_read) || 0,
|
|
156
|
+
cache_creation_input_tokens: Number(usage.cache_creation) || 0,
|
|
157
|
+
});
|
|
158
|
+
usd += priced.usd;
|
|
159
|
+
const label = canonicalizeModelId(rawId);
|
|
160
|
+
perModel.push({ model: label, usd: priced.usd, unknown_model: priced.unknown_model });
|
|
161
|
+
if (priced.unknown_model) unknown.push(label);
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
true_cost_usd: Math.round(usd * 10000) / 10000,
|
|
165
|
+
per_model: perModel,
|
|
166
|
+
unknown_models: Array.from(new Set(unknown)),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Split a session_records `model_usage` map into the 4-tier USD breakdown the
|
|
172
|
+
* cost ledger persists, summed across every model. This is the SERVER-SIDE
|
|
173
|
+
* reconciler's pricing source (GDS-V4 task 1366): when System 1's client cost
|
|
174
|
+
* hook never posted a cost_log row (cloud box / overnight agent with no GDS
|
|
175
|
+
* token, or a digest-posted-but-cost-POST-failed session), the priceable
|
|
176
|
+
* model_usage already on the session_records row is re-priced here into the
|
|
177
|
+
* same fresh/cache_read/cache_write/output split logCost stores.
|
|
178
|
+
*
|
|
179
|
+
* Like priceModelUsage, model_usage has NO 5m/1h cache-creation breakdown — the
|
|
180
|
+
* `cache_creation` lump is priced at the 5m rate, exactly as session-cost.js
|
|
181
|
+
* priceTranscript does in its `else` branch (no breakdown → 5m). Unknown model
|
|
182
|
+
* ids are conservatively priced as opus AND collected, so an unpriced model is
|
|
183
|
+
* loud, never silently $0. Pure: no I/O, no Date.now().
|
|
184
|
+
*
|
|
185
|
+
* @param {Object<string, {input?:number,output?:number,cache_read?:number,cache_creation?:number}>} modelUsage
|
|
186
|
+
* the session_records model_usage shape (NOT the transcript *_input_tokens shape).
|
|
187
|
+
* @returns {{ fresh_input_usd:number, cache_read_usd:number, cache_write_usd:number,
|
|
188
|
+
* output_usd:number, total_usd:number, unknown_models:string[] }}
|
|
189
|
+
* total_usd is the sum of the four tiers; each is the unrounded USD figure (the
|
|
190
|
+
* reconciler rounds at the logCost call site, matching session-cost.js).
|
|
191
|
+
*/
|
|
192
|
+
function componentsFromModelUsage(modelUsage) {
|
|
193
|
+
let fresh_input_usd = 0;
|
|
194
|
+
let cache_read_usd = 0;
|
|
195
|
+
let cache_write_usd = 0;
|
|
196
|
+
let output_usd = 0;
|
|
197
|
+
const unknown = [];
|
|
198
|
+
for (const [rawId, u] of Object.entries(modelUsage || {})) {
|
|
199
|
+
const usage = u || {};
|
|
200
|
+
const fam = familyFor(rawId);
|
|
201
|
+
if (fam === null) unknown.push(canonicalizeModelId(rawId));
|
|
202
|
+
const p = PRICES[fam || 'opus']; // conservative default for an unrecognized model
|
|
203
|
+
fresh_input_usd += ((Number(usage.input) || 0) * p.input) / 1e6;
|
|
204
|
+
output_usd += ((Number(usage.output) || 0) * p.output) / 1e6;
|
|
205
|
+
cache_read_usd += ((Number(usage.cache_read) || 0) * p.cache_read) / 1e6;
|
|
206
|
+
// No 5m/1h split in model_usage → price the cache_creation lump at the 5m rate.
|
|
207
|
+
cache_write_usd += ((Number(usage.cache_creation) || 0) * p.cache_write_5m) / 1e6;
|
|
208
|
+
}
|
|
209
|
+
const total_usd = fresh_input_usd + cache_read_usd + cache_write_usd + output_usd;
|
|
210
|
+
return {
|
|
211
|
+
fresh_input_usd,
|
|
212
|
+
cache_read_usd,
|
|
213
|
+
cache_write_usd,
|
|
214
|
+
output_usd,
|
|
215
|
+
total_usd,
|
|
216
|
+
unknown_models: Array.from(new Set(unknown)),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
module.exports = { PRICES, familyFor, priceUsage, canonicalizeModelId, priceModelUsage, componentsFromModelUsage };
|