@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,185 @@
|
|
|
1
|
+
// tests/migration_namespace.mjs
|
|
2
|
+
//
|
|
3
|
+
// ADR 0108 §5 (configurable-root W5 / task 1885) — cross-repo migration numbering.
|
|
4
|
+
// Pins the pure discipline helpers so the byte-identical-today / collision-proof-tomorrow
|
|
5
|
+
// contract can't silently rot:
|
|
6
|
+
// 1. parseMigrationName splits bare AND namespaced (core_/<key>_) basenames.
|
|
7
|
+
// 2. filenameViolation enforces new core→core_, new module→<key>_, instance bare,
|
|
8
|
+
// while grandfathering the existing bare files (core ≤ 187; game/demo modules).
|
|
9
|
+
// 3. stemCollisions catches the real bug: two sources sharing a schema_migrations stem.
|
|
10
|
+
// 4. nextInNamespace / lineageReport count both forms so an allocator can't reuse a number.
|
|
11
|
+
//
|
|
12
|
+
// No fs/git — the helpers are pure. Run: node tests/migration_namespace.mjs
|
|
13
|
+
|
|
14
|
+
import { strict as assert } from 'node:assert';
|
|
15
|
+
import { createRequire } from 'node:module';
|
|
16
|
+
|
|
17
|
+
const require = createRequire(import.meta.url);
|
|
18
|
+
const ns = require('../scripts/gds/migration-namespace.js');
|
|
19
|
+
|
|
20
|
+
let passed = 0;
|
|
21
|
+
let failed = 0;
|
|
22
|
+
function t(name, fn) {
|
|
23
|
+
try { fn(); passed++; console.log(` PASS ${name}`); }
|
|
24
|
+
catch (e) { failed++; console.log(` FAIL ${name}\n ${e.message}`); }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ---- parseMigrationName ----------------------------------------------------
|
|
28
|
+
t('parseMigrationName: bare NNN_slug.sql', () => {
|
|
29
|
+
const p = ns.parseMigrationName('018_pms_v3_planning_seed.sql');
|
|
30
|
+
assert.equal(p.ok, true);
|
|
31
|
+
assert.equal(p.bare, true);
|
|
32
|
+
assert.equal(p.prefix, null);
|
|
33
|
+
assert.equal(p.number, 18);
|
|
34
|
+
assert.equal(p.slug, 'pms_v3_planning_seed');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
t('parseMigrationName: core_NNN_slug.sql', () => {
|
|
38
|
+
const p = ns.parseMigrationName('core_188_add_widget.sql');
|
|
39
|
+
assert.equal(p.ok, true);
|
|
40
|
+
assert.equal(p.bare, false);
|
|
41
|
+
assert.equal(p.prefix, 'core');
|
|
42
|
+
assert.equal(p.number, 188);
|
|
43
|
+
assert.equal(p.slug, 'add_widget');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
t('parseMigrationName: multi-word module prefix splits at the number, not greedily', () => {
|
|
47
|
+
const p = ns.parseMigrationName('dev_box_003_add_col.sql');
|
|
48
|
+
assert.equal(p.prefix, 'dev_box', 'dev_box_003 → prefix dev_box, not dev');
|
|
49
|
+
assert.equal(p.number, 3);
|
|
50
|
+
assert.equal(p.slug, 'add_col');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
t('parseMigrationName: existing economy/lifecycle files parse as prefixed', () => {
|
|
54
|
+
assert.deepEqual(
|
|
55
|
+
{ prefix: ns.parseMigrationName('economy_001_fix.sql').prefix, number: ns.parseMigrationName('economy_001_fix.sql').number },
|
|
56
|
+
{ prefix: 'economy', number: 1 });
|
|
57
|
+
assert.equal(ns.parseMigrationName('lifecycle_001_goal_first_leads.sql').prefix, 'lifecycle');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
t('parseMigrationName: non-migration names are not migrations', () => {
|
|
61
|
+
for (const n of ['README.md', '.keep', 'notes.txt', 'schema.sql' /* no NNN_ */]) {
|
|
62
|
+
assert.equal(ns.parseMigrationName(n).ok, false, `${n} should not parse as a migration`);
|
|
63
|
+
}
|
|
64
|
+
assert.equal(ns.migrationNumberOf('README.md'), null);
|
|
65
|
+
assert.equal(ns.migrationNumberOf('core_188_x.sql'), 188);
|
|
66
|
+
assert.equal(ns.migrationNumberOf('188_x.sql'), 188);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// ---- filenameViolation: CORE -----------------------------------------------
|
|
70
|
+
t('filenameViolation: legacy bare core (≤187) is grandfathered', () => {
|
|
71
|
+
assert.equal(ns.filenameViolation('core', '003_pms.sql'), null);
|
|
72
|
+
assert.equal(ns.filenameViolation('core', '187_goal_sort_order.sql'), null);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
t('filenameViolation: a NEW bare core (>187) is flagged', () => {
|
|
76
|
+
const v = ns.filenameViolation('core', '188_add_thing.sql');
|
|
77
|
+
assert.ok(v && /core_-prefixed/.test(v), 'new bare core migration must be flagged as needing core_ prefix');
|
|
78
|
+
assert.ok(/core_188_add_thing\.sql/.test(v), 'the fix hint names the namespaced form');
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
t('filenameViolation: a correctly core_-prefixed migration passes', () => {
|
|
82
|
+
assert.equal(ns.filenameViolation('core', 'core_188_add_thing.sql'), null);
|
|
83
|
+
assert.equal(ns.filenameViolation('core', 'core_999_late.sql'), null);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
t('filenameViolation: a core migration wearing another namespace is flagged', () => {
|
|
87
|
+
const v = ns.filenameViolation('core', 'instance_188_x.sql');
|
|
88
|
+
assert.ok(v && /must be core_-prefixed/.test(v));
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// ---- filenameViolation: INSTANCE -------------------------------------------
|
|
92
|
+
t('filenameViolation: instance stays bare (or instance_) — both pass', () => {
|
|
93
|
+
assert.equal(ns.filenameViolation('instance', '188_planning_seed.sql'), null, 'bare instance ok');
|
|
94
|
+
assert.equal(ns.filenameViolation('instance', 'instance_188_planning_seed.sql'), null, 'instance_ prefix ok');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
t('filenameViolation: an instance file wearing the core namespace is flagged', () => {
|
|
98
|
+
const v = ns.filenameViolation('instance', 'core_188_x.sql');
|
|
99
|
+
assert.ok(v && /another source's namespace/.test(v));
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// ---- filenameViolation: MODULE ---------------------------------------------
|
|
103
|
+
t('filenameViolation: legacy bare module (game/demo) grandfathered', () => {
|
|
104
|
+
assert.equal(ns.filenameViolation('module', '001_initial.sql', { moduleKey: 'game' }), null);
|
|
105
|
+
assert.equal(ns.filenameViolation('module', '001_demo_pings.sql', { moduleKey: 'demo' }), null);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
t('filenameViolation: NEW module migration must be <key>_-prefixed', () => {
|
|
109
|
+
const v = ns.filenameViolation('module', '001_first.sql', { moduleKey: 'security' });
|
|
110
|
+
assert.ok(v && /security_-prefixed|security_001_first/.test(v), 'a new non-legacy module bare migration is flagged');
|
|
111
|
+
assert.equal(ns.filenameViolation('module', 'security_001_first.sql', { moduleKey: 'security' }), null);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
t('filenameViolation: hyphenated module key maps to underscore prefix', () => {
|
|
115
|
+
assert.equal(ns.sqlNamespace('dev-box'), 'dev_box');
|
|
116
|
+
assert.equal(ns.filenameViolation('module', 'dev_box_003_x.sql', { moduleKey: 'dev-box' }), null);
|
|
117
|
+
const v = ns.filenameViolation('module', '003_x.sql', { moduleKey: 'dev-box' });
|
|
118
|
+
assert.ok(v && /dev_box_-prefixed|dev_box_003_x/.test(v));
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// ---- stemCollisions --------------------------------------------------------
|
|
122
|
+
t('stemCollisions: none when sources are distinct (the live tree shape)', () => {
|
|
123
|
+
const files = [
|
|
124
|
+
{ source: 'core', basename: '187_a.sql' },
|
|
125
|
+
{ source: 'instance', basename: '186_b.sql' },
|
|
126
|
+
{ source: 'module', moduleKey: 'game', basename: '001_initial.sql' },
|
|
127
|
+
];
|
|
128
|
+
assert.deepEqual(ns.stemCollisions(files), []);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
t('stemCollisions: catches two sources sharing a stem (the silent-skip bug)', () => {
|
|
132
|
+
// Core and instance BOTH allocate a bare 188_add_index → same schema_migrations stem →
|
|
133
|
+
// migrate.sh applies one, silently skips the other. This is the exact hazard.
|
|
134
|
+
const files = [
|
|
135
|
+
{ source: 'core', basename: '188_add_index.sql' },
|
|
136
|
+
{ source: 'instance', basename: '188_add_index.sql' },
|
|
137
|
+
];
|
|
138
|
+
const c = ns.stemCollisions(files);
|
|
139
|
+
assert.equal(c.length, 1);
|
|
140
|
+
assert.equal(c[0].stem, '188_add_index');
|
|
141
|
+
assert.deepEqual(c[0].files, ['core/188_add_index.sql', 'instance/188_add_index.sql']);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
t('stemCollisions: namespacing REMOVES the collision', () => {
|
|
145
|
+
// The cure: core_188_add_index vs 188_add_index → different stems → both apply.
|
|
146
|
+
const files = [
|
|
147
|
+
{ source: 'core', basename: 'core_188_add_index.sql' },
|
|
148
|
+
{ source: 'instance', basename: '188_add_index.sql' },
|
|
149
|
+
];
|
|
150
|
+
assert.deepEqual(ns.stemCollisions(files), []);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// ---- nextInNamespace / lineageReport ---------------------------------------
|
|
154
|
+
t('nextInNamespace: counts bare AND prefixed forms (no number reuse)', () => {
|
|
155
|
+
assert.equal(ns.nextInNamespace(['003_a.sql', 'core_188_b.sql', 'core_190_c.sql']), 191,
|
|
156
|
+
'a prefixed 190 must be counted → next is 191, not 4');
|
|
157
|
+
assert.equal(ns.nextInNamespace([]), 1, 'empty namespace starts at 1');
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
t('lineageReport: independent allocators are safe once namespaced', () => {
|
|
161
|
+
const r = ns.lineageReport({
|
|
162
|
+
core: ['187_x.sql', 'core_188_y.sql'],
|
|
163
|
+
instance: ['186_seed.sql'],
|
|
164
|
+
modulesByKey: { economy: ['economy_001_a.sql'] },
|
|
165
|
+
});
|
|
166
|
+
assert.equal(r.nextCore, 189, 'max(187,188)+1');
|
|
167
|
+
assert.equal(r.nextInstance, 187, 'max(186)+1');
|
|
168
|
+
assert.equal(r.nextByModule.economy, 2);
|
|
169
|
+
assert.deepEqual(r.collisions, []);
|
|
170
|
+
assert.deepEqual(r.violations, []);
|
|
171
|
+
assert.equal(r.consistent, true);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
t('lineageReport: surfaces a real cross-source collision as NOT consistent', () => {
|
|
175
|
+
const r = ns.lineageReport({
|
|
176
|
+
core: ['188_dup.sql'], // bare core >187 → also a filename violation
|
|
177
|
+
instance: ['188_dup.sql'], // same stem as core → collision
|
|
178
|
+
});
|
|
179
|
+
assert.equal(r.consistent, false);
|
|
180
|
+
assert.ok(r.collisions.length >= 1, 'the shared stem is reported');
|
|
181
|
+
assert.ok(r.violations.some((v) => /core_-prefixed/.test(v)), 'the bare-core violation is reported');
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
console.log(`\nmigration_namespace: ${passed} passed, ${failed} failed`);
|
|
185
|
+
process.exit(failed ? 1 : 0);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// tests/migrations_fresh_replay_guard.mjs — core migrations must replay on a FRESH empty DB
|
|
2
|
+
// (task 1238 / ADR 0062 §5+§8). The full proof is scripts/verify-gds-only-schema.sh (needs a live
|
|
3
|
+
// Postgres, so it runs in a PG-present lane, not this DB-free unit gate). This is the cheap static
|
|
4
|
+
// backstop: it locks in the one fix the verifier exposed and stops a future data-coupled
|
|
5
|
+
// task_dependencies seed from silently re-breaking fresh-instance bringup.
|
|
6
|
+
import assert from 'node:assert/strict';
|
|
7
|
+
import { test } from 'node:test';
|
|
8
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
|
|
12
|
+
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
13
|
+
const MIG = path.join(ROOT, 'migrations');
|
|
14
|
+
const GUARD = /IF NOT EXISTS \(\s*SELECT 1 FROM tasks\s*\)/; // the empty-tasks fresh-DB guard
|
|
15
|
+
const coreMigrations = () => readdirSync(MIG).filter((n) => /^\d.*\.sql$/.test(n));
|
|
16
|
+
|
|
17
|
+
test('migration 021 guards its task_dependencies seed against an empty tasks table (task 1238)', () => {
|
|
18
|
+
const sql = readFileSync(path.join(MIG, '021_v3_renumber_and_deps.sql'), 'utf8');
|
|
19
|
+
assert.match(sql, /INSERT INTO task_dependencies/, '021 still carries the dependency seed');
|
|
20
|
+
assert.match(sql, GUARD, '021 must guard the seed so an empty-tasks fresh DB no-ops it');
|
|
21
|
+
// the guard must PRECEDE the first dependency INSERT (otherwise the INSERTs run unguarded)
|
|
22
|
+
assert.ok(
|
|
23
|
+
sql.search(GUARD) < sql.indexOf('INSERT INTO task_dependencies'),
|
|
24
|
+
'the empty-tasks guard must come before the task_dependencies INSERTs'
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('no core migration seeds task_dependencies with literal ids WITHOUT a fresh-DB guard (task 1238)', () => {
|
|
29
|
+
// task_dependencies has an FK to tasks(id); seeding literal ids on a fresh DB FK-violates
|
|
30
|
+
// (ON CONFLICT does NOT suppress an FK violation). Any such seed must be empty-tasks guarded.
|
|
31
|
+
const SEED_RE = /INSERT INTO task_dependencies[^;]*VALUES\s*\(\s*\d/;
|
|
32
|
+
for (const f of coreMigrations()) {
|
|
33
|
+
const sql = readFileSync(path.join(MIG, f), 'utf8');
|
|
34
|
+
if (SEED_RE.test(sql)) {
|
|
35
|
+
assert.match(sql, GUARD, `${f} seeds task_dependencies with literal ids but lacks the empty-tasks fresh-DB guard (task 1238) — it would FK-violate on a fresh instance bringup`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// tests/mirror_lineage_fulltree.mjs — the C9 proof's FULL-TREE acceptance, wired
|
|
2
|
+
// into the DB-free unit gate (task 1703). The sibling tests/mirror_lineage_proof.mjs
|
|
3
|
+
// only exercises the pure helpers (parseEnumChecks / numberingDivergence / …); the
|
|
4
|
+
// actual "the redacted publishable mirror leaks nothing" invariant lived only in
|
|
5
|
+
// mirror-lineage-check.js's runSimulation(), which nothing gated — so it could
|
|
6
|
+
// silently rot (and did: a stray NUL byte made a source file publish UNREDACTED,
|
|
7
|
+
// leaking an instance literal, and no CI check caught it). This test runs the real
|
|
8
|
+
// simulation against the current tree so that regression fails the build.
|
|
9
|
+
//
|
|
10
|
+
// Uses no synthetic fixtures and embeds no instance literal itself: it just invokes
|
|
11
|
+
// runSimulation(), which redacts every publishable file exactly as the export does
|
|
12
|
+
// and asserts zero residual leaks + private⇄public migration-numbering/enum stability.
|
|
13
|
+
// Filesystem + git (git ls-files) are the only dependencies — no DB, no network.
|
|
14
|
+
import assert from 'node:assert/strict';
|
|
15
|
+
import { test } from 'node:test';
|
|
16
|
+
import { createRequire } from 'node:module';
|
|
17
|
+
|
|
18
|
+
const require = createRequire(import.meta.url);
|
|
19
|
+
const { runSimulation } = require('../scripts/gds/mirror-lineage-check.js');
|
|
20
|
+
|
|
21
|
+
test('C9 full-tree simulation: the redacted publishable mirror leaks nothing', () => {
|
|
22
|
+
const report = runSimulation();
|
|
23
|
+
|
|
24
|
+
const leakLines = report.leaks
|
|
25
|
+
.slice(0, 20)
|
|
26
|
+
.map((l) => ` ${l.path}: ${l.label}${l.sample ? ` (${l.sample})` : ''}`)
|
|
27
|
+
.join('\n');
|
|
28
|
+
assert.equal(
|
|
29
|
+
report.leaks.length,
|
|
30
|
+
0,
|
|
31
|
+
`residual instance-literal/secret/IP leak(s) in the redacted mirror — fix mirror-redact.js rules or publish-manifest.js exclusions:\n${leakLines}`
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
assert.equal(
|
|
35
|
+
report.numbering.consistent,
|
|
36
|
+
true,
|
|
37
|
+
`core migration numbering diverged private⇄mirror: missing=[${report.numbering.missing}] extra=[${report.numbering.extra}]`
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
assert.equal(
|
|
41
|
+
report.drift.length,
|
|
42
|
+
0,
|
|
43
|
+
`redaction altered enum value-list(s) in ${report.drift.length} migration(s): ${report.drift.map((d) => d.path).join(', ')}`
|
|
44
|
+
);
|
|
45
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// tests/mirror_lineage_proof.mjs — the C9 lineage-proof pure helpers (V4.R73 /
|
|
2
|
+
// task 1212). DB-free + network-free; picked up by run-unit-tests.js. Uses only
|
|
3
|
+
// synthetic SQL/paths so the published test carries no real instance literal.
|
|
4
|
+
import assert from 'node:assert/strict';
|
|
5
|
+
import { test } from 'node:test';
|
|
6
|
+
import { createRequire } from 'node:module';
|
|
7
|
+
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const {
|
|
10
|
+
migrationNumbersFromPaths, parseEnumChecks, numberingDivergence, enumDrift,
|
|
11
|
+
} = require('../scripts/gds/mirror-lineage-check.js');
|
|
12
|
+
|
|
13
|
+
test('migrationNumbersFromPaths picks CORE migrations only (not module/ADR numbers)', () => {
|
|
14
|
+
const set = migrationNumbersFromPaths([
|
|
15
|
+
'migrations/003_pms.sql',
|
|
16
|
+
'migrations/044_tasks_requires_rank.sql',
|
|
17
|
+
'migrations/060_access_requests.sql',
|
|
18
|
+
'modules/game/migrations/game_001_world.sql', // module migration — excluded
|
|
19
|
+
'docs/adr/0099-delayed-redacted-mirror-export.md', // ADR — excluded
|
|
20
|
+
'src/bongos/db.js', // not a migration
|
|
21
|
+
]);
|
|
22
|
+
assert.deepEqual([...set].sort((a, b) => a - b), [3, 44, 60]);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('parseEnumChecks extracts the quoted value-lists from CHECK (... IN (...))', () => {
|
|
26
|
+
const sql = `
|
|
27
|
+
CREATE TABLE tasks (
|
|
28
|
+
status TEXT NOT NULL CHECK (status IN ('backlog', 'ready', 'active')),
|
|
29
|
+
track TEXT CHECK (track IN ('product', 'internal'))
|
|
30
|
+
);`;
|
|
31
|
+
const lists = parseEnumChecks(sql);
|
|
32
|
+
// Sorted lists, sorted set-of-lists — deterministic.
|
|
33
|
+
assert.deepEqual(lists, [
|
|
34
|
+
["'active'", "'backlog'", "'ready'"],
|
|
35
|
+
["'internal'", "'product'"],
|
|
36
|
+
]);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('parseEnumChecks ignores a non-enum IN (subquery, no string literals)', () => {
|
|
40
|
+
assert.deepEqual(parseEnumChecks('DELETE FROM t WHERE id IN (SELECT id FROM other)'), []);
|
|
41
|
+
assert.deepEqual(parseEnumChecks(''), []);
|
|
42
|
+
assert.deepEqual(parseEnumChecks(null), []);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('enumDrift is EMPTY when redaction only touched a comment domain, not the enum', () => {
|
|
46
|
+
const original = `-- docs: https://widgetco.example/schema\nCHECK (status IN ('backlog', 'ready'))`;
|
|
47
|
+
// A faithful redaction neutralizes the domain but leaves the enum values intact.
|
|
48
|
+
const redacted = `-- docs: https://example.com/schema\nCHECK (status IN ('backlog', 'ready'))`;
|
|
49
|
+
assert.deepEqual(enumDrift([{ path: 'migrations/003_x.sql', original, redacted }]), []);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('enumDrift CATCHES an enum value altered by redaction (the divergence it guards)', () => {
|
|
53
|
+
const original = `CHECK (owner IN ('zoltan', 'admin'))`;
|
|
54
|
+
// A (hypothetical) over-broad owner-redaction that ate an enum value → divergence.
|
|
55
|
+
const redacted = `CHECK (owner IN ('example-owner', 'admin'))`;
|
|
56
|
+
const drift = enumDrift([{ path: 'migrations/003_x.sql', original, redacted }]);
|
|
57
|
+
assert.equal(drift.length, 1);
|
|
58
|
+
assert.equal(drift[0].path, 'migrations/003_x.sql');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('numberingDivergence flags a dropped migration and is otherwise consistent', () => {
|
|
62
|
+
assert.deepEqual(
|
|
63
|
+
numberingDivergence(new Set([1, 2, 3]), new Set([1, 2, 3])),
|
|
64
|
+
{ missing: [], extra: [], consistent: true }
|
|
65
|
+
);
|
|
66
|
+
const dropped = numberingDivergence(new Set([1, 2, 3]), new Set([1, 3]));
|
|
67
|
+
assert.deepEqual(dropped.missing, [2]);
|
|
68
|
+
assert.equal(dropped.consistent, false);
|
|
69
|
+
const gained = numberingDivergence(new Set([1, 2]), new Set([1, 2, 9]));
|
|
70
|
+
assert.deepEqual(gained.extra, [9]);
|
|
71
|
+
assert.equal(gained.consistent, false);
|
|
72
|
+
});
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// tests/mirror_redact.mjs
|
|
2
|
+
//
|
|
3
|
+
// GDS-V4 R72 (task 1211) — locks the public-mirror FILE-LEVEL redactor
|
|
4
|
+
// (scripts/gds/mirror-redact.js, ADR 0098 §6). A silent leak from a publish boundary is
|
|
5
|
+
// catastrophic, so this proves:
|
|
6
|
+
// 1. instance literals (domain + subdomains, repo/db/world token, owner login + alias,
|
|
7
|
+
// company) are redacted; localhost/private/RFC-5737 IPs are KEPT, public IPv4/IPv6
|
|
8
|
+
// (the droplet) are redacted;
|
|
9
|
+
// 2. the no-leak DETECTOR (findLeaks) is STRICTER than redaction — a raw literal
|
|
10
|
+
// substring is caught even where a word-bounded redaction rule would miss it (the
|
|
11
|
+
// `\bowner\b`-inside-a-regex-string gap that bit us during the build);
|
|
12
|
+
// 3. redaction is a fixed point (idempotent) and the secret backstop fires;
|
|
13
|
+
// 4. the SELF-LEAK INVARIANT: the redactor's own (published) source contains NO real
|
|
14
|
+
// instance literal — everything is derived at runtime from branding.
|
|
15
|
+
//
|
|
16
|
+
// Uses a SYNTHETIC instance ("widgetco"/"zoltan") for fixtures so this published test
|
|
17
|
+
// file carries no real instance literal. The self-leak check sources the REAL literals
|
|
18
|
+
// from config/branding.json at runtime (that file is excluded from the mirror), never
|
|
19
|
+
// hard-coding them here.
|
|
20
|
+
//
|
|
21
|
+
// Run: node tests/mirror_redact.mjs
|
|
22
|
+
|
|
23
|
+
import { strict as assert } from 'node:assert';
|
|
24
|
+
import { createRequire } from 'node:module';
|
|
25
|
+
import fs from 'node:fs';
|
|
26
|
+
import path from 'node:path';
|
|
27
|
+
import { fileURLToPath } from 'node:url';
|
|
28
|
+
|
|
29
|
+
const require = createRequire(import.meta.url);
|
|
30
|
+
const R = require('../scripts/gds/mirror-redact.js');
|
|
31
|
+
const {
|
|
32
|
+
buildRedactionRules, collectSensitiveLiterals, redactText, findLeaks, findSecretLeak,
|
|
33
|
+
deriveInstanceLiterals, isPublicRoutableIPv4, isPublicRoutableIPv6, parseIPv6, registrableLabel,
|
|
34
|
+
} = R;
|
|
35
|
+
|
|
36
|
+
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
|
37
|
+
const REPO_ROOT = path.resolve(HERE, '..');
|
|
38
|
+
|
|
39
|
+
// Synthetic instance — non-overlapping coined words so assertions are unambiguous.
|
|
40
|
+
const BRANDING = {
|
|
41
|
+
domains: {
|
|
42
|
+
publicOrigin: 'https://widgetco.com',
|
|
43
|
+
statusOrigin: 'https://status.widgetco.com',
|
|
44
|
+
cookieDomain: '.widgetco.com',
|
|
45
|
+
},
|
|
46
|
+
repo: { owner: 'zoltan', name: 'widgetco' },
|
|
47
|
+
firstAdmin: 'zoltan',
|
|
48
|
+
identity: { worldName: 'Widgetco', company: { name: 'WidgetCorp', site: 'https://widgetcorp.com' } },
|
|
49
|
+
};
|
|
50
|
+
const rules = buildRedactionRules(BRANDING, { owners: ['zoltan-real-name'] });
|
|
51
|
+
const literals = collectSensitiveLiterals(BRANDING, { owners: ['zoltan-real-name'] });
|
|
52
|
+
|
|
53
|
+
let passed = 0, failed = 0;
|
|
54
|
+
function t(name, fn) {
|
|
55
|
+
try { fn(); passed++; console.log(` PASS ${name}`); }
|
|
56
|
+
catch (e) { failed++; console.log(` FAIL ${name}\n ${e.message}`); }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ── domains + subdomains ────────────────────────────────────────────────────────────
|
|
60
|
+
t('domain + subdomains → example.com (subdomain label preserved)', () => {
|
|
61
|
+
const out = redactText('go to https://widgetco.com or https://status.widgetco.com today', rules);
|
|
62
|
+
assert.ok(!/widgetco/i.test(out), `still leaks: ${out}`);
|
|
63
|
+
assert.ok(out.includes('example.com'), out);
|
|
64
|
+
assert.ok(out.includes('status.example.com'), out);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// ── owner login: UNBOUNDED — catches the \bowner\b-in-a-regex gap + home paths ─────────
|
|
68
|
+
t('owner login redacted even preceded by a word char (the audit-authorship.sh gap)', () => {
|
|
69
|
+
const out = redactText("pattern='(\\bzoltan\\b)'; path /Users/zoltan/repo; by zoltan", rules);
|
|
70
|
+
assert.ok(!/zoltan/i.test(out), `still leaks owner: ${out}`);
|
|
71
|
+
assert.ok(out.includes('example-owner'), out);
|
|
72
|
+
});
|
|
73
|
+
t('owner ALIAS (real name / home-dir username) redacted, covering /Users/<alias>', () => {
|
|
74
|
+
const out = redactText('/Users/zoltan-real-name/dev and author zoltan-real-name', rules);
|
|
75
|
+
assert.ok(!/zoltan-real-name/i.test(out), out);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// ── world + company tokens ────────────────────────────────────────────────────────────
|
|
79
|
+
t('world name + company name redacted (case-insensitive)', () => {
|
|
80
|
+
const out = redactText('The Widgetco world, fulfilled by WidgetCorp (widgetcorp.com)', rules);
|
|
81
|
+
assert.ok(!/widgetco/i.test(out), out);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// ── IPv4 floor: public redacted, private/loopback/RFC-5737 kept ───────────────────────
|
|
85
|
+
t('public IPv4 redacted; private/loopback/CGNAT/TEST-NET kept', () => {
|
|
86
|
+
const out = redactText('pub 8.8.8.8 / 104.20.5.9 ; keep 127.0.0.1 10.0.0.1 192.168.1.1 172.16.0.1 169.254.1.1 203.0.113.7 198.51.100.2 192.0.2.9', rules);
|
|
87
|
+
assert.ok(!out.includes('8.8.8.8') && !out.includes('104.20.5.9'), `public IP leaked: ${out}`);
|
|
88
|
+
for (const keep of ['127.0.0.1', '10.0.0.1', '192.168.1.1', '172.16.0.1', '169.254.1.1', '203.0.113.7', '198.51.100.2', '192.0.2.9']) {
|
|
89
|
+
assert.ok(out.includes(keep), `wrongly redacted ${keep}: ${out}`);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
t('isPublicRoutableIPv4 classifier boundaries', () => {
|
|
93
|
+
assert.equal(isPublicRoutableIPv4(104, 236, 254, 243), true);
|
|
94
|
+
assert.equal(isPublicRoutableIPv4(8, 8, 8, 8), true);
|
|
95
|
+
assert.equal(isPublicRoutableIPv4(127, 0, 0, 1), false);
|
|
96
|
+
assert.equal(isPublicRoutableIPv4(10, 1, 2, 3), false);
|
|
97
|
+
assert.equal(isPublicRoutableIPv4(172, 16, 0, 1), false);
|
|
98
|
+
assert.equal(isPublicRoutableIPv4(172, 32, 0, 1), true); // 172.32 is public (outside 16-31)
|
|
99
|
+
assert.equal(isPublicRoutableIPv4(192, 168, 0, 1), false);
|
|
100
|
+
assert.equal(isPublicRoutableIPv4(255, 255, 255, 0), false); // netmask (>=224)
|
|
101
|
+
assert.equal(isPublicRoutableIPv4(203, 0, 113, 1), false); // TEST-NET-3
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// ── IPv6 floor: global unicast redacted, loopback/link-local/ULA kept ─────────────────
|
|
105
|
+
t('public IPv6 (the droplet) redacted; loopback/link-local/ULA kept', () => {
|
|
106
|
+
const out = redactText('v6 2604:a880:800:14:0:2:ee66:b000 keep fe80::1 fc00::5 ::1', rules);
|
|
107
|
+
assert.ok(!out.includes('2604:a880'), `public IPv6 leaked: ${out}`);
|
|
108
|
+
assert.ok(out.includes('fe80::1') && out.includes('fc00::5') && out.includes('::1'), out);
|
|
109
|
+
});
|
|
110
|
+
t('isPublicRoutableIPv6 + a "12:34:56" timestamp is NOT treated as an IP', () => {
|
|
111
|
+
assert.equal(isPublicRoutableIPv6('2604:a880:800:14:0:2:ee66:b000'), true);
|
|
112
|
+
assert.equal(isPublicRoutableIPv6('fe80::1'), false);
|
|
113
|
+
assert.equal(isPublicRoutableIPv6('fc00::5'), false);
|
|
114
|
+
assert.equal(isPublicRoutableIPv6('::1'), false);
|
|
115
|
+
assert.equal(isPublicRoutableIPv6('12:34:56'), false); // only 3 groups, no "::" → not an IPv6
|
|
116
|
+
assert.equal(parseIPv6('2001:db8::1')[0], 0x2001);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// ── the DETECTOR is stricter than redaction ───────────────────────────────────────────
|
|
120
|
+
t('findLeaks catches a raw literal substring a bounded rule would miss', () => {
|
|
121
|
+
// "azoltanb" has no word boundary around zoltan; a \bzoltan\b rule misses it, the
|
|
122
|
+
// substring detector does NOT.
|
|
123
|
+
assert.ok(findLeaks('azoltanb', literals).length > 0);
|
|
124
|
+
assert.ok(findLeaks('inline widgetco reference', literals).length > 0);
|
|
125
|
+
});
|
|
126
|
+
t('findLeaks is clean on fully-redacted output (fixed point)', () => {
|
|
127
|
+
const dirty = 'https://widgetco.com by zoltan at 8.8.8.8 and 2604:a880:800:14:0:2:ee66:b000';
|
|
128
|
+
const clean = redactText(dirty, rules);
|
|
129
|
+
assert.deepEqual(findLeaks(clean, literals), [], `residual leaks: ${JSON.stringify(findLeaks(clean, literals))}`);
|
|
130
|
+
});
|
|
131
|
+
t('findLeaks flags a public IP even with an empty literal list', () => {
|
|
132
|
+
assert.ok(findLeaks('reach 8.8.8.8', []).some((l) => l.label === 'public-ip'));
|
|
133
|
+
assert.deepEqual(findLeaks('reach 127.0.0.1', []), []);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// ── idempotence + secret backstop ─────────────────────────────────────────────────────
|
|
137
|
+
t('redactText is idempotent', () => {
|
|
138
|
+
const once = redactText('https://widgetco.com zoltan 8.8.8.8', rules);
|
|
139
|
+
assert.equal(redactText(once, rules), once);
|
|
140
|
+
});
|
|
141
|
+
t('findSecretLeak detects a secret shape, clean text passes', () => {
|
|
142
|
+
assert.equal(findSecretLeak('token ghp_' + 'a'.repeat(36)), true);
|
|
143
|
+
assert.equal(findSecretLeak('just ordinary prose here'), false);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// ── vanilla instance (empty branding) — IP floor still works, no token/owner rules ────
|
|
147
|
+
t('empty branding derives no tokens/owners but the IP floor still redacts', () => {
|
|
148
|
+
const { tokens, owners } = deriveInstanceLiterals({});
|
|
149
|
+
assert.equal(tokens.size, 0);
|
|
150
|
+
assert.equal(owners.size, 0);
|
|
151
|
+
assert.equal(redactText('ip 8.8.8.8', buildRedactionRules({})).includes('8.8.8.8'), false);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// ── SELF-LEAK INVARIANT: the redactor source carries no REAL instance literal ─────────
|
|
155
|
+
t('mirror-redact.js source contains none of THIS instance\'s literals (sourced at runtime)', () => {
|
|
156
|
+
const brandingPath = path.join(REPO_ROOT, 'config/branding.json');
|
|
157
|
+
if (!fs.existsSync(brandingPath)) { console.log(' (no config/branding.json — vanilla instance, skipping)'); return; }
|
|
158
|
+
const branding = JSON.parse(fs.readFileSync(brandingPath, 'utf8'));
|
|
159
|
+
const src = fs.readFileSync(path.join(REPO_ROOT, 'scripts/gds/mirror-redact.js'), 'utf8').toLowerCase();
|
|
160
|
+
const reals = collectSensitiveLiterals(branding);
|
|
161
|
+
// Also check the registrable domain label explicitly.
|
|
162
|
+
const domLabel = registrableLabel(branding?.domains?.publicOrigin);
|
|
163
|
+
if (domLabel) reals.push(domLabel);
|
|
164
|
+
for (const lit of reals) {
|
|
165
|
+
if (typeof lit === 'string' && lit.length >= 4) {
|
|
166
|
+
assert.ok(!src.includes(lit.toLowerCase()), `redactor source LEAKS instance literal "${lit}" — derive it at runtime instead`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// ── IPv6 boundary guard (task 1688) ─────────────────────────────────────────────────
|
|
172
|
+
// The core packager (scripts/gds/package-core.js) redacts 900+ SOURCE files, exposing
|
|
173
|
+
// a code-vs-prose false positive the prose-heavy mirror rarely hit: a Postgres cast
|
|
174
|
+
// like `$9::bigint` was misread as the address 9:: and CORRUPTED to `$REDACTED_IPbigint`.
|
|
175
|
+
// The guard must kill that false positive with ZERO recall loss on a genuine IPv6.
|
|
176
|
+
t('IPv6 guard: SQL/code `::` casts are neither redacted nor flagged', () => {
|
|
177
|
+
const sql = "now() + ($9::bigint * interval '1 millisecond')";
|
|
178
|
+
assert.equal(R.redactPublicIPs(sql), sql); // no corruption of the cast
|
|
179
|
+
assert.equal(R.firstPublicIP(sql), null); // not flagged as a public IP
|
|
180
|
+
const casts = 'value::int, other::text, beef::json';
|
|
181
|
+
assert.equal(R.redactPublicIPs(casts), casts);
|
|
182
|
+
assert.equal(R.firstPublicIP(casts), null);
|
|
183
|
+
});
|
|
184
|
+
t('IPv6 guard: a genuine public IPv6 is STILL redacted + flagged (no recall loss)', () => {
|
|
185
|
+
const line = 'server = 2606:4700:4700::1111; # dns';
|
|
186
|
+
assert.ok(R.firstPublicIP(line), 'a real public IPv6 must still be detected');
|
|
187
|
+
const red = R.redactPublicIPs(line);
|
|
188
|
+
assert.ok(red.includes(R.REDACTED_IP), 'a real public IPv6 must still be redacted');
|
|
189
|
+
assert.ok(!red.includes('2606:4700'), 'the real address must not survive');
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
console.log(`\n${passed} passed, ${failed} failed`);
|
|
193
|
+
process.exit(failed ? 1 : 0);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// tests/model_alloc_prefs.mjs — per-builder/instance model allocation (task 2011).
|
|
2
|
+
// Pure-shaper unit tests (no DB), mirroring tests/wandering_prefs.mjs.
|
|
3
|
+
import { test } from 'node:test';
|
|
4
|
+
import assert from 'node:assert/strict';
|
|
5
|
+
import { createRequire } from 'node:module';
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const m = require('../modules/builder-settings/model-alloc-prefs.js');
|
|
8
|
+
|
|
9
|
+
test('code defaults when nothing set: main/subagentDefault=opus, routine=haiku', () => {
|
|
10
|
+
const eff = m.effectiveAllocation({}, {});
|
|
11
|
+
assert.deepEqual(eff, { main: 'opus', subagentDefault: 'opus', subagentRoutine: 'haiku' });
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('instance default overrides code default', () => {
|
|
15
|
+
const eff = m.effectiveAllocation({}, { subagentRoutine: 'sonnet' });
|
|
16
|
+
assert.equal(eff.subagentRoutine, 'sonnet');
|
|
17
|
+
assert.equal(eff.main, 'opus'); // untouched → code default
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('builder override wins over instance default', () => {
|
|
21
|
+
const prefs = { model_allocation: { main: 'sonnet' } };
|
|
22
|
+
const eff = m.effectiveAllocation(prefs, { main: 'opus', subagentDefault: 'haiku' });
|
|
23
|
+
assert.equal(eff.main, 'sonnet'); // builder override
|
|
24
|
+
assert.equal(eff.subagentDefault, 'haiku'); // instance default
|
|
25
|
+
assert.equal(eff.subagentRoutine, 'haiku'); // code default
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('invalid tiers/slots are dropped (fall through to lower precedence)', () => {
|
|
29
|
+
const prefs = { model_allocation: { main: 'gpt5', bogus: 'opus' } };
|
|
30
|
+
assert.deepEqual(m.storedOverride(prefs), {}, 'bad tier + unknown slot dropped');
|
|
31
|
+
assert.equal(m.effectiveAllocation(prefs, {}).main, 'opus');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('contract line names all three effective tiers', () => {
|
|
35
|
+
const c = m.contractFor({ model_allocation: { subagentRoutine: 'sonnet' } }, {});
|
|
36
|
+
assert.match(c, /main session: opus/);
|
|
37
|
+
assert.match(c, /subagents default: opus/);
|
|
38
|
+
assert.match(c, /routine plumbing: sonnet/);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('validatePatch: good tier passes, null clears, unknown slot / bad tier → 422', () => {
|
|
42
|
+
assert.deepEqual(m.validatePatch({ main: 'sonnet' }), { ok: true, patch: { main: 'sonnet' } });
|
|
43
|
+
assert.deepEqual(m.validatePatch({ main: null }), { ok: true, patch: { main: null } });
|
|
44
|
+
assert.equal(m.validatePatch({ main: 'gpt5' }).ok, false);
|
|
45
|
+
assert.equal(m.validatePatch({ nope: 'opus' }).ok, false);
|
|
46
|
+
assert.equal(m.validatePatch(42).ok, false);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('applyPatch merges + null clears', () => {
|
|
50
|
+
const base = { main: 'sonnet', subagentRoutine: 'sonnet' };
|
|
51
|
+
assert.deepEqual(m.applyPatch(base, { subagentDefault: 'haiku' }), { main: 'sonnet', subagentRoutine: 'sonnet', subagentDefault: 'haiku' });
|
|
52
|
+
assert.deepEqual(m.applyPatch(base, { main: null }), { subagentRoutine: 'sonnet' });
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('describeForApi exposes catalog + defaults + effective + contract', () => {
|
|
56
|
+
const d = m.describeForApi({ model_allocation: { main: 'sonnet' } }, { subagentRoutine: 'sonnet' });
|
|
57
|
+
assert.ok(Array.isArray(d.slots) && d.slots.length === 3);
|
|
58
|
+
assert.deepEqual(d.code_defaults, { main: 'opus', subagentDefault: 'opus', subagentRoutine: 'haiku' });
|
|
59
|
+
assert.equal(d.instance_default.subagentRoutine, 'sonnet');
|
|
60
|
+
assert.equal(d.override.main, 'sonnet');
|
|
61
|
+
assert.equal(d.effective.main, 'sonnet');
|
|
62
|
+
assert.equal(d.effective.subagentRoutine, 'sonnet');
|
|
63
|
+
});
|