@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,37 @@
|
|
|
1
|
+
# `ideas` module — the idea inbox + blockers + the `ideas.capture` kernel port
|
|
2
|
+
|
|
3
|
+
> The **fourth CORE-domain** carved into a module (BV1.R78, [ADR 0093](../../docs/adr/<redacted>.md) §1) — after memory (R72), grading (R73), and economy (R77). A clean, self-contained slice: its SQL already lived in dedicated `inbox.js`/`blockers.js` files (not the `db.js` monolith), so the carve is a move + a doorway re-point, OTB byte-identical. `default: true` in `module.json` — every instance captures ideas and tracks what's stuck on its owner, so it mounts unconditionally unless explicitly disabled.
|
|
4
|
+
|
|
5
|
+
Owns the **methodology intake surfaces** that feed the backlog: the `idea_inbox` (free-form capture → triage → promote/discard/merge, plus the Metic-proposes / Archon-ratifies `criterion-proposal` flow that writes `done_when_criteria`), and the `blockers` queue (a thing stuck on a human; resolving one auto-promotes its linked `blocked` tasks via a DB trigger).
|
|
6
|
+
|
|
7
|
+
## The boundary (the one rule)
|
|
8
|
+
|
|
9
|
+
This module reaches core **only** through the published doorway `../../src/module-api.js` (`coreVersion ^1.8.0` — it needs the R78 doorway addition `parseId`, the route-param validator alongside `validateOrRespond`/`LIMITS`). It must **never** `require()` a core internal directly, and never another module. Core, in turn, must never `require()` a file in here — it reaches ideas only through the `ideas.capture` port (below). Both directions are enforced by the BV1.R44/R45 fitness checks.
|
|
10
|
+
|
|
11
|
+
## The `ideas.capture` kernel PORT (ADR 0093 §5 — the headline of this carve)
|
|
12
|
+
|
|
13
|
+
- **Provides — port `ideas.capture`** → `inbox.captureIdea`. Registered in `routes/inbox.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). Mirrors `modules/economy/routes/reward.js` (a capability registered from a route factory).
|
|
14
|
+
- **It retires the `captureIdea` doorway leak.** ADR 0091 §3 parked `captureIdea` on `src/module-api.js` as a temporary "domain-leak-pending-carve" because the ideas domain wasn't a module yet. This carve deletes that re-export; the discord `#ideas` inbound (`modules/discord/discord-inbound.js`, the **sole** consumer) now resolves `ideas.capture` at call time instead of importing the doorway helper. This is the codebase's **first module→module port** (every prior port is consumed by core); discord declares it in `consumes`.
|
|
15
|
+
- **Why a verb-noun port, not a doorway re-export:** the same reason `grade`/`reward` are ports — a module capability another module invokes goes behind the kernel switchboard, never a direct import (ADR 0091 §4).
|
|
16
|
+
|
|
17
|
+
## Files
|
|
18
|
+
|
|
19
|
+
| File | What |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `inbox.js` | the `idea_inbox` domain: `captureIdea` (the port provider) + the keyword `classify` fallback, `listOpenIdeas`/`getIdea`/`countOpenIdeas` (with the V3.R70 skill-friction rank-visibility gate), `updateIdea`, and the `ratifyCriterionProposal` transaction (criterion-proposal → `done_when_criteria` + `karma_log` + `criterion_proposal_audit`, all in one `pool.connect()` tx). Reaches the shared pool through the doorway. |
|
|
22
|
+
| `blockers.js` | the `blockers` domain: `listOpenBlockers`/`getBlocker`/`createBlocker`/`resolveBlocker`/`linkBlockerToTask`. `resolveBlocker` relies on the DB trigger on `blockers.status` to auto-promote linked `blocked` tasks. |
|
|
23
|
+
| `routes/inbox.js` | `POST/GET /inbox`, `GET /inbox/:id`, `PATCH /inbox/:id` (Metic+ triage), `POST /inbox/:id/ratify` (Archon). Its factory **registers the `ideas.capture` port**. |
|
|
24
|
+
| `routes/blockers.js` | `GET /blockers` (**public** — the status page reads it), `GET /blockers/:id`, `POST /blockers` (any builder files), `POST /blockers/:id/{resolve,link}` (Metic+). |
|
|
25
|
+
|
|
26
|
+
## NOT in this module (deliberately left in core)
|
|
27
|
+
|
|
28
|
+
- **The public idea/blocker projections** — `routes/public.js` (`projectPublicIdea`/`projectPublicBlocker`) reads `idea_inbox`/`blockers` with its **own** inline `pool.query` SELECTs (existence/ref checks for the hall's `#NNN` deep-link resolver + the public sitemap). Core querying a shared table with its own SQL is allowed; it does **not** import this module, so there is no vendored twin to keep in sync — the boundary is about code imports, not table access.
|
|
29
|
+
- **The ideas/blockers CLIs** — `scripts/gds/{capture,triage,render-ideas}.js` travel with the domain but stay under `scripts/`; they now `require('../../modules/ideas/inbox')` (the economy/memory CLI precedent — `scripts/gds/autonomy-gate.js` does the same for its idea-inbox read).
|
|
30
|
+
|
|
31
|
+
## Tables
|
|
32
|
+
|
|
33
|
+
None owned. `idea_inbox`, `blockers`, `task_blockers`, `criterion_proposal_audit` (+ the `done_when_criteria`/`karma_log` rows the ratify tx touches) were created before the module system and stay in core `migrations/` (the `schema_migrations` stem-key makes a later relocation a no-op). The module owns the *queries*; any **new** ideas migration belongs in `modules/ideas/migrations/` namespaced `ideas_*` (the additive rule).
|
|
34
|
+
|
|
35
|
+
## Tests
|
|
36
|
+
|
|
37
|
+
`tests/criterion_proposal.mjs` imports `modules/ideas/inbox` (the ratify transaction). `tests/discord_inbound.mjs` exercises the consumer (it injects a stub `captureIdea` via dependency injection, so it never hits the real port). `tests/route_validation.mjs` exercises the inbox/blocker write-schemas via the dependency-free `validate()` helper (it imports `_helpers`, not these routes). The doorway-surface contract (`tests/module_api.mjs`) asserts `captureIdea` is **gone** and `parseId` is present. See ADR 0093.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Blockers — DB-canonical replacement for blockers/blockers.md (Phase 2a).
|
|
2
|
+
//
|
|
3
|
+
// A blocker is a thing stuck on a human (typically Lars). When a blocker
|
|
4
|
+
// resolves, a trigger on the blockers table auto-promotes every task linked
|
|
5
|
+
// via task_blockers from 'blocked' → 'ready'.
|
|
6
|
+
//
|
|
7
|
+
// Carved into modules/ideas/ (BV1.R78 / ADR 0093 §1): reaches the shared pool
|
|
8
|
+
// through the published doorway (src/module-api.js). OTB byte-identical.
|
|
9
|
+
|
|
10
|
+
const { pool } = require('../../src/module-api');
|
|
11
|
+
|
|
12
|
+
async function listOpenBlockers() {
|
|
13
|
+
const { rows } = await pool.query(
|
|
14
|
+
`SELECT b.id, b.title, b.body_md, b.status, b.created_at,
|
|
15
|
+
b.source, b.source_ref,
|
|
16
|
+
COALESCE(
|
|
17
|
+
(SELECT array_agg(tb.task_id ORDER BY tb.task_id)
|
|
18
|
+
FROM task_blockers tb WHERE tb.blocker_id = b.id),
|
|
19
|
+
ARRAY[]::bigint[]
|
|
20
|
+
) AS blocking_task_ids
|
|
21
|
+
FROM blockers b
|
|
22
|
+
WHERE b.status = 'open'
|
|
23
|
+
ORDER BY b.id`
|
|
24
|
+
);
|
|
25
|
+
return rows;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function getBlocker(id) {
|
|
29
|
+
const { rows } = await pool.query(
|
|
30
|
+
`SELECT id, title, body_md, status, created_at, resolved_at, resolved_by, resolution_note,
|
|
31
|
+
source, source_ref
|
|
32
|
+
FROM blockers WHERE id = $1`,
|
|
33
|
+
[id]
|
|
34
|
+
);
|
|
35
|
+
return rows[0] || null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Idempotent: if (source, source_ref) is already taken, ON CONFLICT skips.
|
|
39
|
+
// Returns the row when inserted, null when skipped.
|
|
40
|
+
async function createBlocker({ title, bodyMd, source, sourceRef }) {
|
|
41
|
+
if (!title) {
|
|
42
|
+
const e = new Error('title is required');
|
|
43
|
+
e.code = 'TITLE_REQUIRED';
|
|
44
|
+
throw e;
|
|
45
|
+
}
|
|
46
|
+
const { rows } = await pool.query(
|
|
47
|
+
`INSERT INTO blockers (title, body_md, source, source_ref)
|
|
48
|
+
VALUES ($1, $2, $3, $4)
|
|
49
|
+
ON CONFLICT (source, source_ref) WHERE source IS NOT NULL AND source_ref IS NOT NULL
|
|
50
|
+
DO NOTHING
|
|
51
|
+
RETURNING id, title, body_md, status, created_at, source, source_ref`,
|
|
52
|
+
[title, bodyMd ?? '', source ?? null, sourceRef ?? null]
|
|
53
|
+
);
|
|
54
|
+
return rows[0] || null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Resolve a blocker. The trigger on blockers.status flips linked tasks
|
|
58
|
+
// from 'blocked' → 'ready' atomically.
|
|
59
|
+
async function resolveBlocker({ id, builderId, resolutionNote }) {
|
|
60
|
+
const { rows } = await pool.query(
|
|
61
|
+
`UPDATE blockers
|
|
62
|
+
SET status = 'resolved',
|
|
63
|
+
resolved_by = $2,
|
|
64
|
+
resolution_note = $3
|
|
65
|
+
WHERE id = $1 AND status = 'open'
|
|
66
|
+
RETURNING id, title, status, resolved_at, resolved_by, resolution_note`,
|
|
67
|
+
[id, builderId, resolutionNote ?? null]
|
|
68
|
+
);
|
|
69
|
+
if (rows.length === 0) {
|
|
70
|
+
const e = new Error('blocker not found or already resolved');
|
|
71
|
+
e.code = 'BLOCKER_NOT_OPEN';
|
|
72
|
+
throw e;
|
|
73
|
+
}
|
|
74
|
+
// After-the-fact: count how many tasks the trigger just promoted.
|
|
75
|
+
const { rows: promoted } = await pool.query(
|
|
76
|
+
`SELECT id, title FROM tasks
|
|
77
|
+
WHERE id IN (SELECT task_id FROM task_blockers WHERE blocker_id = $1)
|
|
78
|
+
AND status = 'ready'`,
|
|
79
|
+
[id]
|
|
80
|
+
);
|
|
81
|
+
return { blocker: rows[0], promoted_tasks: promoted };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Link a blocker to a task (lives in task_blockers via the new blocker_id col).
|
|
85
|
+
async function linkBlockerToTask({ blockerId, taskId }) {
|
|
86
|
+
await pool.query(
|
|
87
|
+
`INSERT INTO task_blockers (task_id, blocker_id, blocker_ref)
|
|
88
|
+
VALUES ($1, $2, $3)
|
|
89
|
+
ON CONFLICT DO NOTHING`,
|
|
90
|
+
[taskId, blockerId, `blocker:${blockerId}`]
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module.exports = {
|
|
95
|
+
listOpenBlockers,
|
|
96
|
+
getBlocker,
|
|
97
|
+
createBlocker,
|
|
98
|
+
resolveBlocker,
|
|
99
|
+
linkBlockerToTask,
|
|
100
|
+
};
|
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
// GDS idea_inbox helpers — structured replacement for free-form generative-ideas.md.
|
|
2
|
+
//
|
|
3
|
+
// Schema (migration 006_pms_v2.sql):
|
|
4
|
+
// idea_inbox(id, title, body_md, kind, suggested_version, suggested_priority,
|
|
5
|
+
// captured_at, captured_by, status, promoted_to_task_id, reviewed_at)
|
|
6
|
+
//
|
|
7
|
+
// kind values match tasks.kind (feature | bug | infra | refactor | spike |
|
|
8
|
+
// learning-capture | cleanup | decision | blocker-resolution | unclassified).
|
|
9
|
+
// status values are 'open' | 'promoted' | 'discarded' | 'merged'.
|
|
10
|
+
//
|
|
11
|
+
// Carved into modules/ideas/ (BV1.R78 / ADR 0093 §1): the ideas domain reaches
|
|
12
|
+
// the shared pool through the published doorway (src/module-api.js — the only
|
|
13
|
+
// core file a module may require, ADR 0083). OTB byte-identical.
|
|
14
|
+
|
|
15
|
+
const { pool } = require('../../src/module-api');
|
|
16
|
+
|
|
17
|
+
const VALID_KINDS = [
|
|
18
|
+
'feature',
|
|
19
|
+
'bug',
|
|
20
|
+
'infra',
|
|
21
|
+
'refactor',
|
|
22
|
+
'spike',
|
|
23
|
+
'learning-capture',
|
|
24
|
+
'cleanup',
|
|
25
|
+
'decision',
|
|
26
|
+
'blocker-resolution',
|
|
27
|
+
'unclassified',
|
|
28
|
+
// V3.R31 (#252) — Metics propose new version criteria via idea_inbox with
|
|
29
|
+
// structured body_md { target_version, criterion_md, sort_order_hint }.
|
|
30
|
+
// Archon ratifies via POST /api/gds/inbox/:id/ratify, which atomically
|
|
31
|
+
// inserts a done_when_criteria row, marks the idea promoted, awards karma,
|
|
32
|
+
// and writes a criterion_proposal_audit row. The kind value gates the
|
|
33
|
+
// ratify endpoint (assert kind='criterion-proposal' before promotion).
|
|
34
|
+
// CHECK constraint updated in migration 042.
|
|
35
|
+
'criterion-proposal',
|
|
36
|
+
];
|
|
37
|
+
const VALID_STATUSES = ['open', 'promoted', 'discarded', 'merged'];
|
|
38
|
+
|
|
39
|
+
// -------------------------------------------------------------------------
|
|
40
|
+
// Skill-friction tagging (task V3.R70 / #289)
|
|
41
|
+
//
|
|
42
|
+
// The nightly `skill-usage-review` routine files one idea_inbox row per
|
|
43
|
+
// friction pattern it detects. The done-when calls these "kind='skill-friction'"
|
|
44
|
+
// rows, but the DB CHECK constraint on idea_inbox.kind (migration 006) only
|
|
45
|
+
// admits the fixed task-kind enum — adding a literal 'skill-friction' kind
|
|
46
|
+
// would need a new migration, and migrations are explicitly out of scope for
|
|
47
|
+
// this task. So we tag friction rows the same way overnight-code-review tags
|
|
48
|
+
// its findings: a stable title prefix. The underlying `kind` stays a valid
|
|
49
|
+
// enum value (cleanup), and SKILL_FRICTION_TAG is the machine-checkable marker.
|
|
50
|
+
//
|
|
51
|
+
// When the GDS-V3 rank system (V3.R04) lands a real builders.rank column +
|
|
52
|
+
// idea_inbox.kind migration, this prefix convention can be promoted to a
|
|
53
|
+
// first-class kind value and this marker collapses to a kind check.
|
|
54
|
+
const SKILL_FRICTION_TAG = '[skill-friction]';
|
|
55
|
+
|
|
56
|
+
// -------------------------------------------------------------------------
|
|
57
|
+
// Rank visibility (task V3.R70 / #289)
|
|
58
|
+
//
|
|
59
|
+
// Three ranks are planned in GDS-V3 (V3.R04): Xenos (default for any
|
|
60
|
+
// GitHub-authed person), Metic (Archon-approved), Archon. Skill-friction
|
|
61
|
+
// ideas are a system-evolution signal meant for trusted builders — Xenos
|
|
62
|
+
// must NOT see them in their inbox view; Metic and Archon may.
|
|
63
|
+
//
|
|
64
|
+
// `builders.rank` does not exist in the schema yet (it lands with R04), and
|
|
65
|
+
// requireBuilder does not yet populate req.builder.rank — so today every
|
|
66
|
+
// caller passes viewerRank=null. The gate is written to be correct the moment
|
|
67
|
+
// rank is threaded through: it hides skill-friction rows ONLY when the viewer
|
|
68
|
+
// is positively known to be Xenos. Unknown/absent rank (today's reality, where
|
|
69
|
+
// no Xenos exist yet) is treated as Metic+ and sees everything — so wiring this
|
|
70
|
+
// in does not regress current all-builders behavior.
|
|
71
|
+
const XENOS_RANK = 'xenos';
|
|
72
|
+
|
|
73
|
+
function rankCanSeeSkillFriction(viewerRank) {
|
|
74
|
+
// Hide only when we KNOW the viewer is Xenos. null/undefined/anything else
|
|
75
|
+
// (Metic, Archon, or "rank system not deployed") => allowed.
|
|
76
|
+
if (viewerRank == null) return true;
|
|
77
|
+
return String(viewerRank).toLowerCase() !== XENOS_RANK;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// -------------------------------------------------------------------------
|
|
81
|
+
// Fallback classifier — keyword heuristics over title+body.
|
|
82
|
+
//
|
|
83
|
+
// Will be superseded by the real auto-classifier shipping in task #33 (B1).
|
|
84
|
+
// Kept as a self-contained function here so this task does not depend on B1
|
|
85
|
+
// and so B1 can drop in by re-exporting `classify` from a shared module.
|
|
86
|
+
// -------------------------------------------------------------------------
|
|
87
|
+
function classify(title, body = '') {
|
|
88
|
+
const text = `${title || ''} ${body || ''}`.toLowerCase();
|
|
89
|
+
|
|
90
|
+
// Order matters: more specific patterns first.
|
|
91
|
+
// "blocker" before "infra" because "blocker on infra" should classify as
|
|
92
|
+
// blocker-resolution, not infra.
|
|
93
|
+
if (/\b(blocker|blocked\s|waiting\s+on|unblock)\b/.test(text)) return 'blocker-resolution';
|
|
94
|
+
if (/\b(fix|broken|bug|regression|doesn'?t\s+work|isn'?t\s+working|crash|error)\b/.test(text)) return 'bug';
|
|
95
|
+
if (/\b(refactor|clean\s+up|rename|move\s|extract|consolidate)\b/.test(text)) return 'refactor';
|
|
96
|
+
if (/\b(research|spike|investigate|explore|prototype)\b/.test(text)) return 'spike';
|
|
97
|
+
if (/\b(learn|took\s+me|gotcha|discovered|tip\s+for|note\s+to\s+self)\b/.test(text)) return 'learning-capture';
|
|
98
|
+
if (/\b(decide|choose|pick\s|should\s+we|which\s+approach)\b/.test(text)) return 'decision';
|
|
99
|
+
if (/\b(deploy|infra|ops|monitoring|ci\b|cd\b|systemd|caddy|nginx)\b/.test(text)) return 'infra';
|
|
100
|
+
if (/\b(remove|delete|kill\s|deprecate|drop\s)\b/.test(text)) return 'cleanup';
|
|
101
|
+
return 'feature';
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// -------------------------------------------------------------------------
|
|
105
|
+
// Capture
|
|
106
|
+
// -------------------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
async function captureIdea({
|
|
109
|
+
title,
|
|
110
|
+
bodyMd = '',
|
|
111
|
+
kind,
|
|
112
|
+
suggestedVersion = null,
|
|
113
|
+
suggestedPriority = null,
|
|
114
|
+
capturedBy = null,
|
|
115
|
+
}) {
|
|
116
|
+
if (!title || typeof title !== 'string') {
|
|
117
|
+
throw { code: 'TITLE_REQUIRED' };
|
|
118
|
+
}
|
|
119
|
+
const resolvedKind = kind || classify(title, bodyMd);
|
|
120
|
+
if (!VALID_KINDS.includes(resolvedKind)) {
|
|
121
|
+
throw { code: 'BAD_KIND', kind: resolvedKind };
|
|
122
|
+
}
|
|
123
|
+
if (
|
|
124
|
+
suggestedPriority != null &&
|
|
125
|
+
!(Number.isInteger(suggestedPriority) && suggestedPriority >= 1 && suggestedPriority <= 5)
|
|
126
|
+
) {
|
|
127
|
+
throw { code: 'BAD_PRIORITY', priority: suggestedPriority };
|
|
128
|
+
}
|
|
129
|
+
const { rows } = await pool.query(
|
|
130
|
+
`INSERT INTO idea_inbox
|
|
131
|
+
(title, body_md, kind, suggested_version, suggested_priority, captured_by, status)
|
|
132
|
+
VALUES ($1, $2, $3, $4, $5, $6, 'open')
|
|
133
|
+
RETURNING id, title, body_md, kind, suggested_version, suggested_priority,
|
|
134
|
+
captured_at, captured_by, status, promoted_to_task_id, reviewed_at`,
|
|
135
|
+
[title, bodyMd, resolvedKind, suggestedVersion, suggestedPriority, capturedBy]
|
|
136
|
+
);
|
|
137
|
+
return rows[0];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// -------------------------------------------------------------------------
|
|
141
|
+
// Read
|
|
142
|
+
// -------------------------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
// viewerRank gates skill-friction visibility (V3.R70 / #289): Xenos must not
|
|
145
|
+
// see skill-friction rows; Metic+ (or unknown rank, pre-R04) see everything.
|
|
146
|
+
// We filter in SQL when the viewer is positively Xenos so the LIMIT still
|
|
147
|
+
// returns up to `limit` *visible* rows rather than `limit` rows that then get
|
|
148
|
+
// thinned out in JS. The skill-friction marker is a title prefix (see
|
|
149
|
+
// SKILL_FRICTION_TAG above) because the kind enum cannot take a new value
|
|
150
|
+
// without a migration.
|
|
151
|
+
async function listOpenIdeas({ kind = null, limit = 50, viewerRank = null } = {}) {
|
|
152
|
+
const params = [];
|
|
153
|
+
const where = [`status = 'open'`];
|
|
154
|
+
if (kind) {
|
|
155
|
+
params.push(kind);
|
|
156
|
+
where.push(`kind = $${params.length}`);
|
|
157
|
+
}
|
|
158
|
+
if (!rankCanSeeSkillFriction(viewerRank)) {
|
|
159
|
+
params.push(`${SKILL_FRICTION_TAG}%`);
|
|
160
|
+
where.push(`title NOT LIKE $${params.length}`);
|
|
161
|
+
}
|
|
162
|
+
params.push(limit);
|
|
163
|
+
const { rows } = await pool.query(
|
|
164
|
+
`SELECT id, title, body_md, kind, suggested_version, suggested_priority,
|
|
165
|
+
captured_at, captured_by, status, promoted_to_task_id, reviewed_at
|
|
166
|
+
FROM idea_inbox
|
|
167
|
+
WHERE ${where.join(' AND ')}
|
|
168
|
+
ORDER BY captured_at DESC
|
|
169
|
+
LIMIT $${params.length}`,
|
|
170
|
+
params
|
|
171
|
+
);
|
|
172
|
+
return rows;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async function getIdea(id) {
|
|
176
|
+
const { rows } = await pool.query(
|
|
177
|
+
`SELECT id, title, body_md, kind, suggested_version, suggested_priority,
|
|
178
|
+
captured_at, captured_by, status, promoted_to_task_id, reviewed_at
|
|
179
|
+
FROM idea_inbox
|
|
180
|
+
WHERE id = $1`,
|
|
181
|
+
[id]
|
|
182
|
+
);
|
|
183
|
+
return rows[0] ?? null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// viewerRank applies the SAME skill-friction visibility gate as listOpenIdeas
|
|
187
|
+
// (V3.R70 / #289) so the count a viewer is shown matches the rows they can see:
|
|
188
|
+
// a Xenos must not be told there are N open ideas when [skill-friction] rows
|
|
189
|
+
// are filtered out of their list. Default null preserves the old "count
|
|
190
|
+
// everything" behaviour for callers that don't have (or don't gate on) a rank.
|
|
191
|
+
async function countOpenIdeas({ viewerRank = null } = {}) {
|
|
192
|
+
const params = [];
|
|
193
|
+
const where = [`status = 'open'`];
|
|
194
|
+
if (!rankCanSeeSkillFriction(viewerRank)) {
|
|
195
|
+
params.push(`${SKILL_FRICTION_TAG}%`);
|
|
196
|
+
where.push(`title NOT LIKE $${params.length}`);
|
|
197
|
+
}
|
|
198
|
+
const { rows } = await pool.query(
|
|
199
|
+
`SELECT count(*)::int AS n FROM idea_inbox WHERE ${where.join(' AND ')}`,
|
|
200
|
+
params
|
|
201
|
+
);
|
|
202
|
+
return rows[0].n;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// -------------------------------------------------------------------------
|
|
206
|
+
// Update / merge
|
|
207
|
+
// -------------------------------------------------------------------------
|
|
208
|
+
|
|
209
|
+
async function updateIdea(id, { status, kind, promoted_to_task_id, reviewed_at } = {}) {
|
|
210
|
+
const sets = [];
|
|
211
|
+
const params = [id];
|
|
212
|
+
if (status !== undefined) {
|
|
213
|
+
if (!VALID_STATUSES.includes(status)) throw { code: 'BAD_STATUS', status };
|
|
214
|
+
params.push(status);
|
|
215
|
+
sets.push(`status = $${params.length}`);
|
|
216
|
+
}
|
|
217
|
+
if (kind !== undefined) {
|
|
218
|
+
if (!VALID_KINDS.includes(kind)) throw { code: 'BAD_KIND', kind };
|
|
219
|
+
params.push(kind);
|
|
220
|
+
sets.push(`kind = $${params.length}`);
|
|
221
|
+
}
|
|
222
|
+
if (promoted_to_task_id !== undefined) {
|
|
223
|
+
params.push(promoted_to_task_id);
|
|
224
|
+
sets.push(`promoted_to_task_id = $${params.length}`);
|
|
225
|
+
}
|
|
226
|
+
if (reviewed_at !== undefined) {
|
|
227
|
+
params.push(reviewed_at);
|
|
228
|
+
sets.push(`reviewed_at = $${params.length}`);
|
|
229
|
+
}
|
|
230
|
+
if (sets.length === 0) {
|
|
231
|
+
return getIdea(id);
|
|
232
|
+
}
|
|
233
|
+
const { rows } = await pool.query(
|
|
234
|
+
`UPDATE idea_inbox
|
|
235
|
+
SET ${sets.join(', ')}
|
|
236
|
+
WHERE id = $1
|
|
237
|
+
RETURNING id, title, body_md, kind, suggested_version, suggested_priority,
|
|
238
|
+
captured_at, captured_by, status, promoted_to_task_id, reviewed_at`,
|
|
239
|
+
params
|
|
240
|
+
);
|
|
241
|
+
if (rows.length === 0) throw { code: 'IDEA_NOT_FOUND' };
|
|
242
|
+
return rows[0];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// -------------------------------------------------------------------------
|
|
246
|
+
// Criterion-proposal ratification (V3.R31 / #252)
|
|
247
|
+
//
|
|
248
|
+
// Atomically promotes an idea_inbox row with kind='criterion-proposal' into a
|
|
249
|
+
// real done_when_criteria row, marks the idea as promoted, awards karma to
|
|
250
|
+
// the proposer (delta=+3, reason='proposal_ratified'), and writes an audit
|
|
251
|
+
// row capturing who proposed / who ratified / when / what.
|
|
252
|
+
//
|
|
253
|
+
// Called by POST /api/gds/inbox/:id/ratify (Archon-only, gated by requireRank
|
|
254
|
+
// in the router). The body_md of the source idea is parsed as JSON with the
|
|
255
|
+
// shape { target_version, criterion_md, sort_order_hint }; malformed bodies
|
|
256
|
+
// throw BAD_BODY so the route can return a structured 400.
|
|
257
|
+
//
|
|
258
|
+
// Karma amount is tunable; V3.R28 (#248) sets it to +3 to recognize good civic
|
|
259
|
+
// input without overweighting it relative to peer-upvote signals that arrive
|
|
260
|
+
// in volume. criterion_id on the new done_when_criteria row defaults to
|
|
261
|
+
// "proposal-<idea_id>" so the (version_id, criterion_id) UNIQUE constraint
|
|
262
|
+
// fires if someone ratifies the same idea twice — the second attempt fails the
|
|
263
|
+
// transaction rather than creating a duplicate criterion silently.
|
|
264
|
+
const KARMA_RATIFY_DELTA = 3;
|
|
265
|
+
const KARMA_RATIFY_REASON = 'proposal_ratified';
|
|
266
|
+
|
|
267
|
+
function parseProposalBody(bodyMd) {
|
|
268
|
+
if (!bodyMd || typeof bodyMd !== 'string') {
|
|
269
|
+
throw { code: 'BAD_BODY', reason: 'body_md_empty' };
|
|
270
|
+
}
|
|
271
|
+
let parsed;
|
|
272
|
+
try {
|
|
273
|
+
parsed = JSON.parse(bodyMd);
|
|
274
|
+
} catch (err) {
|
|
275
|
+
throw { code: 'BAD_BODY', reason: 'body_md_not_json', detail: err.message };
|
|
276
|
+
}
|
|
277
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
278
|
+
throw { code: 'BAD_BODY', reason: 'body_md_not_object' };
|
|
279
|
+
}
|
|
280
|
+
const { target_version, criterion_md, sort_order_hint } = parsed;
|
|
281
|
+
if (!target_version || typeof target_version !== 'string') {
|
|
282
|
+
throw { code: 'BAD_BODY', reason: 'target_version_required' };
|
|
283
|
+
}
|
|
284
|
+
if (!criterion_md || typeof criterion_md !== 'string') {
|
|
285
|
+
throw { code: 'BAD_BODY', reason: 'criterion_md_required' };
|
|
286
|
+
}
|
|
287
|
+
let hint = null;
|
|
288
|
+
if (sort_order_hint != null) {
|
|
289
|
+
const n = Number(sort_order_hint);
|
|
290
|
+
if (!Number.isFinite(n) || !Number.isInteger(n)) {
|
|
291
|
+
throw { code: 'BAD_BODY', reason: 'sort_order_hint_not_integer' };
|
|
292
|
+
}
|
|
293
|
+
hint = n;
|
|
294
|
+
}
|
|
295
|
+
return { target_version, criterion_md, sort_order_hint: hint };
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async function ratifyCriterionProposal(ideaId, ratifierId, { notesMd = '' } = {}) {
|
|
299
|
+
const id = Number(ideaId);
|
|
300
|
+
if (!Number.isFinite(id)) {
|
|
301
|
+
throw { code: 'BAD_ID' };
|
|
302
|
+
}
|
|
303
|
+
const rid = Number(ratifierId);
|
|
304
|
+
if (!Number.isFinite(rid)) {
|
|
305
|
+
throw { code: 'BAD_RATIFIER' };
|
|
306
|
+
}
|
|
307
|
+
const client = await pool.connect();
|
|
308
|
+
try {
|
|
309
|
+
await client.query('BEGIN');
|
|
310
|
+
|
|
311
|
+
// a. Read + lock the idea row.
|
|
312
|
+
const { rows: ideaRows } = await client.query(
|
|
313
|
+
`SELECT id, title, body_md, kind, status, captured_by
|
|
314
|
+
FROM idea_inbox
|
|
315
|
+
WHERE id = $1
|
|
316
|
+
FOR UPDATE`,
|
|
317
|
+
[id]
|
|
318
|
+
);
|
|
319
|
+
if (ideaRows.length === 0) throw { code: 'IDEA_NOT_FOUND' };
|
|
320
|
+
const idea = ideaRows[0];
|
|
321
|
+
if (idea.kind !== 'criterion-proposal') {
|
|
322
|
+
throw { code: 'WRONG_KIND', kind: idea.kind, expected: 'criterion-proposal' };
|
|
323
|
+
}
|
|
324
|
+
if (idea.status !== 'open') {
|
|
325
|
+
throw { code: 'IDEA_NOT_OPEN', status: idea.status };
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// b. Parse body_md.
|
|
329
|
+
const proposal = parseProposalBody(idea.body_md);
|
|
330
|
+
|
|
331
|
+
// c. Verify target version exists. (FK on done_when_criteria.version_id
|
|
332
|
+
// would catch this too, but giving a 400 instead of a 23503 is friendlier.)
|
|
333
|
+
const { rows: verRows } = await client.query(
|
|
334
|
+
`SELECT id FROM versions WHERE id = $1`,
|
|
335
|
+
[proposal.target_version]
|
|
336
|
+
);
|
|
337
|
+
if (verRows.length === 0) {
|
|
338
|
+
throw { code: 'VERSION_NOT_FOUND', version_id: proposal.target_version };
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// d. Resolve sort_order: prefer the hint; otherwise max(existing)+1, or 100
|
|
342
|
+
// if no rows exist yet (matches the migration 006 default).
|
|
343
|
+
let sortOrder = proposal.sort_order_hint;
|
|
344
|
+
if (sortOrder == null) {
|
|
345
|
+
const { rows: maxRows } = await client.query(
|
|
346
|
+
`SELECT COALESCE(MAX(sort_order), 0) + 1 AS next
|
|
347
|
+
FROM done_when_criteria
|
|
348
|
+
WHERE version_id = $1`,
|
|
349
|
+
[proposal.target_version]
|
|
350
|
+
);
|
|
351
|
+
sortOrder = maxRows[0].next;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// e. INSERT done_when_criteria with criterion_id = 'proposal-<idea_id>'.
|
|
355
|
+
// The UNIQUE (version_id, criterion_id) constraint provides natural
|
|
356
|
+
// idempotency — re-ratifying the same idea would 23505 here.
|
|
357
|
+
const criterionRefId = `proposal-${idea.id}`;
|
|
358
|
+
const { rows: critRows } = await client.query(
|
|
359
|
+
`INSERT INTO done_when_criteria
|
|
360
|
+
(version_id, criterion_id, criterion_md, sort_order)
|
|
361
|
+
VALUES ($1, $2, $3, $4)
|
|
362
|
+
RETURNING id, version_id, criterion_id, criterion_md, sort_order`,
|
|
363
|
+
[proposal.target_version, criterionRefId, proposal.criterion_md, sortOrder]
|
|
364
|
+
);
|
|
365
|
+
const criterion = critRows[0];
|
|
366
|
+
|
|
367
|
+
// f. Mark the idea promoted. promoted_to_task_id stays NULL — a criterion
|
|
368
|
+
// is not a task. reviewed_at is stamped to now() so triage views skip it.
|
|
369
|
+
await client.query(
|
|
370
|
+
`UPDATE idea_inbox
|
|
371
|
+
SET status = 'promoted',
|
|
372
|
+
promoted_to_task_id = NULL,
|
|
373
|
+
reviewed_at = now()
|
|
374
|
+
WHERE id = $1`,
|
|
375
|
+
[idea.id]
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
// g. Award karma to the proposer. captured_by may be NULL on legacy rows;
|
|
379
|
+
// skip the karma insert in that case (no proposer to credit) but still
|
|
380
|
+
// record the audit row.
|
|
381
|
+
let karmaAwarded = 0;
|
|
382
|
+
if (idea.captured_by != null) {
|
|
383
|
+
await client.query(
|
|
384
|
+
`INSERT INTO karma_log (builder_id, delta, reason, granted_by)
|
|
385
|
+
VALUES ($1, $2, $3, $4)`,
|
|
386
|
+
[idea.captured_by, KARMA_RATIFY_DELTA, KARMA_RATIFY_REASON, rid]
|
|
387
|
+
);
|
|
388
|
+
karmaAwarded = KARMA_RATIFY_DELTA;
|
|
389
|
+
|
|
390
|
+
// Note: prior to 2026-05-30 this also ticked a 'first_vote_received'
|
|
391
|
+
// onboarding stage. That stage was removed (migration 059) — graduation
|
|
392
|
+
// no longer waits on a peer vote — so there is nothing to mark here now.
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// h. Audit row — durable record of the ratification event.
|
|
396
|
+
const { rows: auditRows } = await client.query(
|
|
397
|
+
`INSERT INTO criterion_proposal_audit
|
|
398
|
+
(idea_id, criterion_id, proposed_by, ratified_by,
|
|
399
|
+
target_version, criterion_md, sort_order_hint, notes_md)
|
|
400
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
401
|
+
RETURNING id, ratified_at`,
|
|
402
|
+
[
|
|
403
|
+
idea.id,
|
|
404
|
+
criterion.id,
|
|
405
|
+
idea.captured_by,
|
|
406
|
+
rid,
|
|
407
|
+
proposal.target_version,
|
|
408
|
+
proposal.criterion_md,
|
|
409
|
+
proposal.sort_order_hint,
|
|
410
|
+
notesMd || '',
|
|
411
|
+
]
|
|
412
|
+
);
|
|
413
|
+
|
|
414
|
+
await client.query('COMMIT');
|
|
415
|
+
return {
|
|
416
|
+
criterion_id: criterion.id,
|
|
417
|
+
criterion_ref: criterion.criterion_id,
|
|
418
|
+
version_id: criterion.version_id,
|
|
419
|
+
sort_order: criterion.sort_order,
|
|
420
|
+
audit_id: auditRows[0].id,
|
|
421
|
+
ratified_at: auditRows[0].ratified_at,
|
|
422
|
+
karma_awarded: karmaAwarded,
|
|
423
|
+
proposer_id: idea.captured_by,
|
|
424
|
+
};
|
|
425
|
+
} catch (err) {
|
|
426
|
+
await client.query('ROLLBACK').catch(() => {});
|
|
427
|
+
throw err;
|
|
428
|
+
} finally {
|
|
429
|
+
client.release();
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// -------------------------------------------------------------------------
|
|
434
|
+
// Helpers used by CLI defaults
|
|
435
|
+
// -------------------------------------------------------------------------
|
|
436
|
+
|
|
437
|
+
module.exports = {
|
|
438
|
+
// classifier (exported for tests + future B1 swap-in)
|
|
439
|
+
classify,
|
|
440
|
+
VALID_KINDS,
|
|
441
|
+
VALID_STATUSES,
|
|
442
|
+
// skill-friction tagging + rank visibility gate (V3.R70 / #289)
|
|
443
|
+
SKILL_FRICTION_TAG,
|
|
444
|
+
XENOS_RANK,
|
|
445
|
+
rankCanSeeSkillFriction,
|
|
446
|
+
// capture
|
|
447
|
+
captureIdea,
|
|
448
|
+
// read
|
|
449
|
+
listOpenIdeas,
|
|
450
|
+
getIdea,
|
|
451
|
+
countOpenIdeas,
|
|
452
|
+
// mutate
|
|
453
|
+
updateIdea,
|
|
454
|
+
// criterion-proposal ratification (V3.R31 / #252)
|
|
455
|
+
ratifyCriterionProposal,
|
|
456
|
+
parseProposalBody,
|
|
457
|
+
KARMA_RATIFY_DELTA,
|
|
458
|
+
KARMA_RATIFY_REASON,
|
|
459
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"key": "ideas",
|
|
3
|
+
"title": "Ideas",
|
|
4
|
+
"description": "The idea inbox (capture, triage, criterion-proposal ratification) and the blockers queue — the methodology surfaces that feed the backlog. A core-domain module carved out of the GDS core in BV1.R78 (ADR 0093 §1); default-on because every instance captures ideas and tracks what's stuck on its owner. Registers the `ideas.capture` kernel PORT the discord #ideas inbound resolves (ADR 0093 §5 — retiring the temporary `captureIdea` doorway leak).",
|
|
5
|
+
"coreVersion": "^1.8.0",
|
|
6
|
+
"default": true,
|
|
7
|
+
"contributes": { "routes": ["inbox", "blockers"] },
|
|
8
|
+
"provides": ["ideas.capture"],
|
|
9
|
+
"consumes": []
|
|
10
|
+
}
|