@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,684 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// scripts/gds/package-core.js — produce the Cloud Bongos CORE as a versioned,
|
|
5
|
+
// installable, PINNABLE artifact a downstream project vendors.
|
|
6
|
+
// GDS-V4 R84 (task 1688), implementing ADR 0100 §1 (the two-repo instance model).
|
|
7
|
+
//
|
|
8
|
+
// This is the FIRST step of the R84 → R85 → R86 spine: package the core (here) →
|
|
9
|
+
// stand Mercury up on a pinned core (R85, #1689) → make `bongos upgrade` a real
|
|
10
|
+
// update-consumption channel (R86, #1690). A Cloud Bongos *instance* may be a
|
|
11
|
+
// SEPARATE repository that installs a pinned version of this core and layers its
|
|
12
|
+
// own content/branding/modules on top (the physical realization of ADR 0062 §1).
|
|
13
|
+
//
|
|
14
|
+
// WHAT "the core" IS — reused, never re-defined:
|
|
15
|
+
// The core is exactly the subtree scripts/gds/publish-manifest.isPublishable()
|
|
16
|
+
// already defines (ADR 0098) — the portable methodology + platform + neutral
|
|
17
|
+
// branding. There is NO second allow-list here; this tool CONSUMES that one.
|
|
18
|
+
//
|
|
19
|
+
// HOW IT DIFFERS FROM public-mirror-export.js (R72 / ADR 0099):
|
|
20
|
+
// - The mirror is the DELAYED (≈6-month), redacted, PUBLIC open-source surface —
|
|
21
|
+
// a whole separate git repo, published on a schedule. Its job is transparency,
|
|
22
|
+
// so it REDACTS every file (topology + brand kept out of a world-readable repo).
|
|
23
|
+
// - This artifact is a CURRENT, versioned, installable UNIT a downstream repo
|
|
24
|
+
// vendors + pins to a version. Its job is dependency consumption. No lag. It must
|
|
25
|
+
// BOOT, so functional files ship VERBATIM — redacting them corrupts npm integrity
|
|
26
|
+
// hashes + SQL identifiers (the R88 boot failure; task 1824). Only DOCS (.md) are
|
|
27
|
+
// genericized; brand/topology in code ships as-is (public, not secrets).
|
|
28
|
+
// The two share the same file SELECTION (isPublishable) and REUSE the same redaction
|
|
29
|
+
// primitives (redactBlob/findLeaks), but apply them differently — see processCoreFile.
|
|
30
|
+
//
|
|
31
|
+
// ONE FAIL-CLOSED PASS (task 1824 — docs redacted, functional verbatim):
|
|
32
|
+
// 1. Resolve the source ref → commit; enumerate its tree (git ls-tree).
|
|
33
|
+
// 2. PARTITION through isPublishable() — the single source of truth.
|
|
34
|
+
// 3. Per file, IN MEMORY (processCoreFile): DOCS (.md) are genericized + secret-scrubbed
|
|
35
|
+
// like the mirror; FUNCTIONAL files are kept VERBATIM and scanned only for an exact
|
|
36
|
+
// live-credential leak (brand/IP hits are non-fatal ADVISORIES, surfaced for a human).
|
|
37
|
+
// 4. NO-LEAK GATE (fail-closed): if any DOC leaks post-redaction, or any FUNCTIONAL file
|
|
38
|
+
// carries a live credential verbatim, PRODUCE NOTHING — dist/ is never touched. The
|
|
39
|
+
// in-memory pass makes the abort atomic (same discipline as the mirror export).
|
|
40
|
+
// 5. Only when the whole set is clean: write the tree to
|
|
41
|
+
// dist/cloudbongos-core-<version>/, the .tgz, and the pin MANIFEST.
|
|
42
|
+
//
|
|
43
|
+
// THE VERSION STAMP is the platform version — src/module-api.js CORE_VERSION,
|
|
44
|
+
// read via the SAME fail-soft accessor scripts/gds/module.js + bongos upgrade use
|
|
45
|
+
// (task 1203). That shared coordinate is what keeps the R84→R86 spine coherent.
|
|
46
|
+
//
|
|
47
|
+
// THE PIN is `tree_sha256` in the manifest: a canonical hash over the redacted
|
|
48
|
+
// core files (path\0mode\0filehash per line, sorted). It is INDEPENDENT of the
|
|
49
|
+
// tar/gzip byte layout, so a consumer pins on { core_version, source_commit,
|
|
50
|
+
// tree_sha256 } and verifies an install by recomputing it from the unpacked tree.
|
|
51
|
+
// The manifest ALSO records tarball.sha256 to verify the exact downloaded bytes.
|
|
52
|
+
//
|
|
53
|
+
// USAGE:
|
|
54
|
+
// node scripts/gds/package-core.js [--ref <git-ref>] [--out-dir dist]
|
|
55
|
+
// [--version <v>] [--droplet-ip <ip>] [--publish [--live]]
|
|
56
|
+
// Defaults: --ref HEAD, --out-dir dist, --version = platform CORE_VERSION.
|
|
57
|
+
// Outputs (nothing is committed — dist/ is gitignored):
|
|
58
|
+
// dist/cloudbongos-core-<version>/ the redacted core tree (inspectable)
|
|
59
|
+
// dist/cloudbongos-core-<version>.tgz the installable unit
|
|
60
|
+
// dist/cloudbongos-core-<version>.manifest.json the PIN (tree hash + per-file hashes)
|
|
61
|
+
// --publish after building, `npm publish` the .tgz as a PRIVATE scoped
|
|
62
|
+
// package (--access restricted). DRY-RUN unless --live is added
|
|
63
|
+
// (task 2089 / ADR 0134). Private publish needs the cloudbongos
|
|
64
|
+
// npm org on a paid plan + `npm login`; this script holds no token.
|
|
65
|
+
|
|
66
|
+
const fs = require('node:fs');
|
|
67
|
+
const path = require('node:path');
|
|
68
|
+
const zlib = require('node:zlib');
|
|
69
|
+
const crypto = require('node:crypto');
|
|
70
|
+
const { execFileSync, spawnSync } = require('node:child_process');
|
|
71
|
+
|
|
72
|
+
const REPO_ROOT = path.resolve(__dirname, '..', '..');
|
|
73
|
+
|
|
74
|
+
// Reuse — never re-type. The core definition, the redaction, and the tree parser
|
|
75
|
+
// all already exist and are unit-tested at their homes.
|
|
76
|
+
const { isPublishable } = require(path.join(REPO_ROOT, 'scripts/gds/publish-manifest.js'));
|
|
77
|
+
const {
|
|
78
|
+
buildRedactionRules, collectSensitiveLiterals, findLeaks,
|
|
79
|
+
} = require(path.join(REPO_ROOT, 'scripts/gds/mirror-redact.js'));
|
|
80
|
+
const { collectEnvSecrets } = require(path.join(REPO_ROOT, 'modules/security/secret-scrub.js'));
|
|
81
|
+
const { redactBlob, parseLsTree } = require(path.join(REPO_ROOT, 'scripts/public-mirror-export.js'));
|
|
82
|
+
|
|
83
|
+
const MANIFEST_SCHEMA = 1;
|
|
84
|
+
const ARTIFACT_NAME = 'cloudbongos-core';
|
|
85
|
+
// The tar internal root MUST be `package/` — that is the one hardcoded npm
|
|
86
|
+
// convention for an installable tarball (`npm install ./x.tgz` / `npm pack`
|
|
87
|
+
// output both use it; npm does not read the directory name to find package.json,
|
|
88
|
+
// it always looks for `package/package.json`). The ARTIFACT_NAME-named on-disk
|
|
89
|
+
// stage dir (stageDirName, below) is unrelated — that is just a local inspection
|
|
90
|
+
// path, not what ships inside the .tgz (ADR 0108 §2, task 1882).
|
|
91
|
+
const TAR_ROOT = 'package/';
|
|
92
|
+
// The self-describing manifest carried INSIDE the artifact (minus tarball.* — a
|
|
93
|
+
// file cannot contain its own hash). The authoritative PIN is the side-car next
|
|
94
|
+
// to the .tgz, which adds tarball.{sha256,bytes}.
|
|
95
|
+
const INNER_MANIFEST = `${TAR_ROOT}.cloudbongos-core.json`;
|
|
96
|
+
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// The platform version — read CORE_VERSION via the doorway, lazily + fail-soft,
|
|
99
|
+
// mirroring scripts/gds/module.js:coreVersion() so this artifact stamps the SAME
|
|
100
|
+
// coordinate `bongos upgrade` and the module loader compare against (task 1203).
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
function coreVersion() {
|
|
103
|
+
try { return require(path.join(REPO_ROOT, 'src/module-api')).CORE_VERSION; }
|
|
104
|
+
catch { return '1.0.0'; }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
// Pure helpers (exported for tests — no I/O, no git, no network)
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
|
|
111
|
+
function sha256hex(buf) {
|
|
112
|
+
return crypto.createHash('sha256').update(buf).digest('hex');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// CONSUMER-CORE extraction policy (task 1824) — the file-classification layer.
|
|
117
|
+
//
|
|
118
|
+
// The R84 packager wrongly reused the PUBLIC-MIRROR redaction (redactBlob) over EVERY
|
|
119
|
+
// file, which CORRUPTED the functional core: the secret scrubber blanks npm integrity
|
|
120
|
+
// hashes (base64 → looks secret) + Postgres identifiers (matched an env-secret substring),
|
|
121
|
+
// which broke `npm ci` and turned 63 migrations into `CREATE FUNCTION <redacted>()` SQL
|
|
122
|
+
// errors — the R88 boot failure (proof: docs/reviews/2026-07-03-cloud-bongos-separation-proof.md).
|
|
123
|
+
//
|
|
124
|
+
// The correction: the consumer core takes FUNCTIONAL files (code, SQL, JSON, lockfiles —
|
|
125
|
+
// everything that is not a .md doc) VERBATIM. Redaction stays a DOCS + public-mirror
|
|
126
|
+
// concern (ADR 0099). Brand identity (domain/owner/world) and the droplet IP legitimately
|
|
127
|
+
// pepper the functional core — hall-link comments (`example.com/builders#/task/N`), the
|
|
128
|
+
// `DROPLET` deploy constant in ship.js, seed migrations — and are PUBLIC, not secrets, so
|
|
129
|
+
// they ship as-is (a downstream instance rebrands via config) and are only WARNED about,
|
|
130
|
+
// never scrubbed or aborted-on. Aborting on them would fail ~189 files and the extraction
|
|
131
|
+
// would never succeed. The ONE hard gate on a functional file is an exact live-CREDENTIAL
|
|
132
|
+
// match (an env-secret VALUE appearing verbatim) — that IS a real leak. Genuine secrets are
|
|
133
|
+
// already kept out at SOURCE (husky + CI TruffleHog) and .env* is manifest-excluded, so this
|
|
134
|
+
// gate has ~zero false positives (a real high-entropy token never appears by accident).
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
const DOC_RE = /\.(md|markdown)$/i;
|
|
137
|
+
function isDocPath(p) { return DOC_RE.test(String(p || '')); }
|
|
138
|
+
|
|
139
|
+
// Fail-loud gate for a FUNCTIONAL file: only an exact live-credential value (an env-secret
|
|
140
|
+
// VALUE present verbatim, >= 8 chars) is a real leak. The sample is withheld (it's a secret).
|
|
141
|
+
function functionalSecretLeaks(view, envSecrets) {
|
|
142
|
+
const out = [];
|
|
143
|
+
for (const s of envSecrets || []) {
|
|
144
|
+
if (typeof s === 'string' && s.length >= 8 && view.includes(s)) out.push({ label: 'live-credential' });
|
|
145
|
+
}
|
|
146
|
+
return out;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Classify + process one publishable file → { buf, leaks, advisories, kind }.
|
|
150
|
+
// * DOC (.md): genericized + secret-scrubbed like the mirror (redactBlob), gated with the
|
|
151
|
+
// full detector — a downstream's vendored ADRs/recipes should not carry this brand. Any
|
|
152
|
+
// residual leak after redaction is FATAL (`leaks`).
|
|
153
|
+
// * FUNCTIONAL: VERBATIM buffer. `leaks` = exact live-credential matches only (FATAL).
|
|
154
|
+
// `advisories` = brand-identity substrings + public IPs that ship as-is (non-fatal, for
|
|
155
|
+
// human awareness) — REUSES findLeaks so the detector is defined once.
|
|
156
|
+
function processCoreFile({ pathRel, raw, rules, sensitiveLiterals, envSecrets }) {
|
|
157
|
+
if (isDocPath(pathRel)) {
|
|
158
|
+
const r = redactBlob({ buf: raw, rules, sensitiveLiterals, envSecrets });
|
|
159
|
+
const leaks = r.leaks.map((l) => ({ label: `doc:${l.label}`, sample: l.sample }));
|
|
160
|
+
if (r.secret) leaks.push({ label: 'doc:secret-shape' });
|
|
161
|
+
return { buf: r.buf, leaks, advisories: [], kind: 'doc' };
|
|
162
|
+
}
|
|
163
|
+
const view = raw.toString('latin1'); // ASCII-safe byte view for both text + binary
|
|
164
|
+
return {
|
|
165
|
+
buf: raw,
|
|
166
|
+
leaks: functionalSecretLeaks(view, envSecrets),
|
|
167
|
+
advisories: findLeaks(view, sensitiveLiterals),
|
|
168
|
+
kind: 'functional',
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ---------------------------------------------------------------------------
|
|
173
|
+
// The CORE's own package.json + package-lock.json (task 1882, ADR 0108 §2).
|
|
174
|
+
//
|
|
175
|
+
// The source repo's package.json/package-lock.json (isPublishable() includes
|
|
176
|
+
// both) are GAME-heavy — colyseus/phaser/sharp/discord.js plus the repo's own
|
|
177
|
+
// name/version — and are not what a downstream `npm install @cloudbongos/core`
|
|
178
|
+
// should see. These two files are SYNTHESIZED here (never copied verbatim from
|
|
179
|
+
// git) and staged in their place. Everything else still ships through the
|
|
180
|
+
// normal isPublishable()/processCoreFile path.
|
|
181
|
+
//
|
|
182
|
+
// Core deps are express + pg (+ an undici pin) — ADR 0108 §Context. discord.js
|
|
183
|
+
// (+ its undici requirement) is an OPTIONAL MODULE dependency, not core; a
|
|
184
|
+
// consumer that enables the discord module installs it itself.
|
|
185
|
+
const CORE_DEP_NAMES = ['express', 'pg'];
|
|
186
|
+
|
|
187
|
+
// Pure — takes the source package.json's `dependencies`/`overrides` as plain
|
|
188
|
+
// objects so this is unit-testable with no disk I/O. Throws if a required core
|
|
189
|
+
// dep is missing from the source (a real inconsistency, not a silent drop).
|
|
190
|
+
function buildPackageJson({ version, sourceDeps, sourceOverrides }) {
|
|
191
|
+
const dependencies = {};
|
|
192
|
+
for (const name of CORE_DEP_NAMES) {
|
|
193
|
+
const range = sourceDeps && sourceDeps[name];
|
|
194
|
+
if (!range) throw new Error(`package-core: source package.json is missing required core dependency "${name}"`);
|
|
195
|
+
dependencies[name] = range;
|
|
196
|
+
}
|
|
197
|
+
const pkg = {
|
|
198
|
+
name: '@cloudbongos/core',
|
|
199
|
+
version,
|
|
200
|
+
description: 'Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).',
|
|
201
|
+
license: 'AGPL-3.0-or-later',
|
|
202
|
+
main: 'src/platform-server.js',
|
|
203
|
+
bin: { bongos: 'bin/bongos.js' },
|
|
204
|
+
// Named exports a consumer imports directly, alongside the default entry
|
|
205
|
+
// (buildPlatformApp, from `main`): mountInternalSurfaces (the shared
|
|
206
|
+
// host-routing surface both server.js and platform-server.js call) and the
|
|
207
|
+
// module-api doorway a module's routes/seams are authored against.
|
|
208
|
+
exports: {
|
|
209
|
+
'.': './src/platform-server.js',
|
|
210
|
+
'./serve-internal': './src/bongos/serve-internal.js',
|
|
211
|
+
'./module-api': './src/module-api.js',
|
|
212
|
+
},
|
|
213
|
+
engines: { node: '>=22' },
|
|
214
|
+
// Pre-launch distribution posture (task 2089 / ADR 0134): publish PRIVATE by
|
|
215
|
+
// default. `access:"restricted"` makes a scoped package private on publish, so a
|
|
216
|
+
// paid npm org can ship it where only members can install — no accidental public
|
|
217
|
+
// leak if someone forgets the CLI flag. Going public at launch is one step:
|
|
218
|
+
// `npm access public @cloudbongos/core` (or flip this to "public"). The name must
|
|
219
|
+
// stay SCOPED to be private at all — unscoped npm names are always public.
|
|
220
|
+
publishConfig: { access: 'restricted' },
|
|
221
|
+
dependencies,
|
|
222
|
+
};
|
|
223
|
+
if (sourceOverrides && sourceOverrides.undici) pkg.overrides = { undici: sourceOverrides.undici };
|
|
224
|
+
return pkg;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// ---------------------------------------------------------------------------
|
|
228
|
+
// package-lock.json pruning — restrict the shipped lockfile to the CORE's own
|
|
229
|
+
// dependency closure (express + pg), dropping the game's ~225 other transitive
|
|
230
|
+
// packages. Pure + OFFLINE: walks the EXISTING (already-resolved) lockfile
|
|
231
|
+
// graph with the same node_modules lookup order Node's own require() uses
|
|
232
|
+
// (check "<pkgPath>/node_modules/<dep>", then walk up stripping the trailing
|
|
233
|
+
// "node_modules/<segment>" and retry, up to the top-level "node_modules/<dep>")
|
|
234
|
+
// rather than re-resolving against the npm registry — so packaging never needs
|
|
235
|
+
// network access, and can never disagree with how the source lockfile itself
|
|
236
|
+
// was resolved (verified against the live 307-package lockfile: an 82-package
|
|
237
|
+
// closure, including the nested send/node_modules/ms version-conflict case).
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
|
|
240
|
+
// Resolve `depName` as required FROM `fromPath` (a "node_modules/..." packages
|
|
241
|
+
// key, or '' for the root) against `packages` — returns the matching key, or
|
|
242
|
+
// undefined if genuinely absent.
|
|
243
|
+
function resolveLockDep(packages, fromPath, depName) {
|
|
244
|
+
const segments = fromPath ? fromPath.split('/node_modules/') : [];
|
|
245
|
+
for (let i = segments.length; i >= 0; i--) {
|
|
246
|
+
const prefix = segments.slice(0, i).join('/node_modules/');
|
|
247
|
+
const candidate = prefix ? `${prefix}/node_modules/${depName}` : `node_modules/${depName}`;
|
|
248
|
+
if (packages[candidate]) return candidate;
|
|
249
|
+
}
|
|
250
|
+
return undefined;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// BFS the dependency + optionalDependency closure of `rootDepNames` from the
|
|
254
|
+
// lockfile root. Throws on an unresolvable dependency — a real lockfile
|
|
255
|
+
// inconsistency, not something to silently drop from the shipped artifact.
|
|
256
|
+
function lockfileClosure(packages, rootDepNames) {
|
|
257
|
+
const keep = new Set();
|
|
258
|
+
const queue = [];
|
|
259
|
+
for (const name of rootDepNames) {
|
|
260
|
+
const key = resolveLockDep(packages, '', name);
|
|
261
|
+
if (!key) throw new Error(`package-core: lockfile has no resolved entry for root dependency "${name}"`);
|
|
262
|
+
queue.push(key);
|
|
263
|
+
}
|
|
264
|
+
while (queue.length) {
|
|
265
|
+
const key = queue.shift();
|
|
266
|
+
if (keep.has(key)) continue;
|
|
267
|
+
keep.add(key);
|
|
268
|
+
const deps = { ...(packages[key].dependencies || {}), ...(packages[key].optionalDependencies || {}) };
|
|
269
|
+
for (const depName of Object.keys(deps)) {
|
|
270
|
+
const depKey = resolveLockDep(packages, key, depName);
|
|
271
|
+
if (!depKey) throw new Error(`package-core: lockfile has no resolved entry for "${depName}" required by "${key}"`);
|
|
272
|
+
if (!keep.has(depKey)) queue.push(depKey);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return keep;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Pure — takes the already-parsed source lockfile + the CORE's own
|
|
279
|
+
// name/version/dependency-ranges (the same ranges buildPackageJson emitted, so
|
|
280
|
+
// the two files never drift). `rootDepNames` defaults to CORE_DEP_NAMES.
|
|
281
|
+
function prunePackageLock(sourceLock, { name, version, rootRanges, rootDepNames = CORE_DEP_NAMES }) {
|
|
282
|
+
const packages = sourceLock.packages || {};
|
|
283
|
+
const keep = lockfileClosure(packages, rootDepNames);
|
|
284
|
+
const prunedPackages = {
|
|
285
|
+
'': { name, version, license: 'AGPL-3.0-or-later', dependencies: { ...rootRanges } },
|
|
286
|
+
};
|
|
287
|
+
for (const key of [...keep].sort()) prunedPackages[key] = packages[key];
|
|
288
|
+
return {
|
|
289
|
+
name,
|
|
290
|
+
version,
|
|
291
|
+
lockfileVersion: sourceLock.lockfileVersion,
|
|
292
|
+
requires: true,
|
|
293
|
+
packages: prunedPackages,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// The PIN. A canonical, compression-independent digest of the core tree: one
|
|
298
|
+
// "path\0mode\0filesha256\n" line per file, byte-sorted by path. A consumer
|
|
299
|
+
// recomputes this from the unpacked tree to prove an install matches the pin.
|
|
300
|
+
// `files` = [{ path, mode, sha256 }]. Modes are normalized so the pin is stable
|
|
301
|
+
// regardless of the checkout's umask.
|
|
302
|
+
function canonicalTreeHash(files) {
|
|
303
|
+
const lines = (files || [])
|
|
304
|
+
.map((f) => `${f.path}\u0000${normalizeMode(f.mode)}\u0000${f.sha256}`)
|
|
305
|
+
.sort();
|
|
306
|
+
return sha256hex(Buffer.from(lines.join('\n') + '\n', 'utf8'));
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Collapse ANY mode form — git's 100644/100755, our canonical 0000644/0000755, or a
|
|
310
|
+
// raw filesystem octal string like "755" — to two canonical tar modes, keyed only on
|
|
311
|
+
// the executable bit. IDEMPOTENT (normalizeMode(normalizeMode(x)) === normalizeMode(x))
|
|
312
|
+
// AND exec-aware, so the tree pin reproduces byte-identically whether a consumer
|
|
313
|
+
// recomputes it from the manifest's files[] (already-canonical modes) or from the
|
|
314
|
+
// unpacked tree's stat() modes. Expects a STRING (git mode / canonical mode / octal).
|
|
315
|
+
function normalizeMode(mode) {
|
|
316
|
+
const s = String(mode);
|
|
317
|
+
if (s === '100755' || s === '0000755' || s === '755') return '0000755';
|
|
318
|
+
const n = parseInt(s, 8);
|
|
319
|
+
if (Number.isFinite(n) && (n & 0o111)) return '0000755';
|
|
320
|
+
return '0000644';
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// The pin manifest (WITHOUT tarball.* — added by withTarballInfo for the side-car).
|
|
324
|
+
function buildCoreManifest({
|
|
325
|
+
version, coreContract, sourceCommit, sourceRef, builtAtIso, files, treeHash, redaction,
|
|
326
|
+
}) {
|
|
327
|
+
return {
|
|
328
|
+
artifact: ARTIFACT_NAME,
|
|
329
|
+
manifest_schema: MANIFEST_SCHEMA,
|
|
330
|
+
generator: 'scripts/gds/package-core.js',
|
|
331
|
+
// core_version is the PIN coordinate (the platform version, task 1203).
|
|
332
|
+
// core_contract is the module-doorway semver (src/module-api CORE_VERSION);
|
|
333
|
+
// equal to core_version unless --version overrides. A module pinned to
|
|
334
|
+
// "^core_contract" is guaranteed to load against this core.
|
|
335
|
+
core_version: version,
|
|
336
|
+
core_contract: coreContract,
|
|
337
|
+
source_commit: sourceCommit,
|
|
338
|
+
source_ref: sourceRef,
|
|
339
|
+
built_at: builtAtIso,
|
|
340
|
+
redaction: redaction || null,
|
|
341
|
+
file_count: files.length,
|
|
342
|
+
// tree_sha256 is the authoritative integrity pin (see canonicalTreeHash).
|
|
343
|
+
tree_sha256: treeHash,
|
|
344
|
+
files: files.map((f) => ({ path: f.path, mode: normalizeMode(f.mode), sha256: f.sha256 })),
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// The side-car pin = the inner manifest + the exact-bytes coordinate of THIS .tgz.
|
|
349
|
+
function withTarballInfo(manifest, tarball) {
|
|
350
|
+
return { ...manifest, tarball };
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function tarballName(version) { return `${ARTIFACT_NAME}-${version}.tgz`; }
|
|
354
|
+
function manifestName(version) { return `${ARTIFACT_NAME}-${version}.manifest.json`; }
|
|
355
|
+
function stageDirName(version) { return `${ARTIFACT_NAME}-${version}`; }
|
|
356
|
+
|
|
357
|
+
// ---- a minimal, correct, DETERMINISTIC ustar+gzip writer (node-only, #686) ----
|
|
358
|
+
// Deterministic (fixed mtime/uid/gid, normalized mode, sorted entries) so the same
|
|
359
|
+
// source yields byte-identical bytes — a bonus over the tree_sha256 pin. Long paths
|
|
360
|
+
// use the ustar name/prefix split, falling back to a GNU 'L' longname entry (read
|
|
361
|
+
// by GNU tar, bsdtar/macOS, and node-tar) for the rare path that won't split.
|
|
362
|
+
|
|
363
|
+
function octal(n, width) {
|
|
364
|
+
// width-1 octal digits, zero-padded, then a NUL — the classic numeric field.
|
|
365
|
+
return Buffer.from(n.toString(8).padStart(width - 1, '0').slice(-(width - 1)) + '\0', 'ascii');
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function tarChecksum(block) {
|
|
369
|
+
let sum = 0;
|
|
370
|
+
for (let i = 0; i < 512; i++) sum += (i >= 148 && i < 156) ? 0x20 : block[i];
|
|
371
|
+
return sum;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Build one 512-byte ustar header. `name`/`prefix` must already fit (<=100 / <=155).
|
|
375
|
+
function ustarHeader({ name, prefix = '', mode, size, typeflag }) {
|
|
376
|
+
const h = Buffer.alloc(512, 0);
|
|
377
|
+
h.write(name, 0, 100, 'utf8');
|
|
378
|
+
octal(mode, 8).copy(h, 100);
|
|
379
|
+
octal(0, 8).copy(h, 108); // uid
|
|
380
|
+
octal(0, 8).copy(h, 116); // gid
|
|
381
|
+
octal(size, 12).copy(h, 124);
|
|
382
|
+
octal(0, 12).copy(h, 136); // mtime = 0 (determinism)
|
|
383
|
+
h.write(typeflag, 156, 1, 'ascii');
|
|
384
|
+
h.write('ustar\0', 257, 6, 'ascii');
|
|
385
|
+
h.write('00', 263, 2, 'ascii');
|
|
386
|
+
if (prefix) h.write(prefix, 345, 155, 'utf8');
|
|
387
|
+
// checksum field: 6 octal digits + NUL + space, computed with the field = spaces.
|
|
388
|
+
const cksum = tarChecksum(h);
|
|
389
|
+
h.write(cksum.toString(8).padStart(6, '0').slice(-6) + '\0 ', 148, 8, 'ascii');
|
|
390
|
+
return h;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Split a >100-byte path into { name<=100, prefix<=155 } at a '/' boundary, or
|
|
394
|
+
// return null if no split fits (→ caller uses the GNU longname fallback).
|
|
395
|
+
function splitUstarName(fullPath) {
|
|
396
|
+
const bytes = Buffer.byteLength(fullPath, 'utf8');
|
|
397
|
+
if (bytes <= 100) return { name: fullPath, prefix: '' };
|
|
398
|
+
// Find the LAST '/' such that the tail (after it) is <=100 and the head <=155.
|
|
399
|
+
for (let i = fullPath.length - 1; i > 0; i--) {
|
|
400
|
+
if (fullPath[i] !== '/') continue;
|
|
401
|
+
const prefix = fullPath.slice(0, i);
|
|
402
|
+
const name = fullPath.slice(i + 1);
|
|
403
|
+
if (Buffer.byteLength(name, 'utf8') <= 100 && Buffer.byteLength(prefix, 'utf8') <= 155) {
|
|
404
|
+
return { name, prefix };
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function padTo512(buf) {
|
|
411
|
+
const rem = buf.length % 512;
|
|
412
|
+
return rem === 0 ? buf : Buffer.concat([buf, Buffer.alloc(512 - rem, 0)]);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// GNU longname pseudo-entry: a header (typeflag 'L', name '././@LongLink') whose
|
|
416
|
+
// BODY is the full path (incl. trailing NUL), immediately followed by the real
|
|
417
|
+
// file entry. Read by GNU tar, bsdtar/macOS, and node-tar.
|
|
418
|
+
function gnuLongName(fullPath) {
|
|
419
|
+
const payload = Buffer.from(fullPath + '\0', 'utf8');
|
|
420
|
+
const hdr = ustarHeader({ name: '././@LongLink', mode: 0o644, size: payload.length, typeflag: 'L' });
|
|
421
|
+
return Buffer.concat([hdr, padTo512(payload)]);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// entries: [{ name, mode, buf }] — `name` includes the TAR_ROOT prefix. Returns a
|
|
425
|
+
// gzip'd tar Buffer. Pure + deterministic given sorted entries.
|
|
426
|
+
function buildTar(entries) {
|
|
427
|
+
const sorted = [...entries].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
428
|
+
const chunks = [];
|
|
429
|
+
for (const e of sorted) {
|
|
430
|
+
const mode = e.mode & 0o7777;
|
|
431
|
+
const split = splitUstarName(e.name);
|
|
432
|
+
if (split) {
|
|
433
|
+
chunks.push(ustarHeader({ name: split.name, prefix: split.prefix, mode, size: e.buf.length, typeflag: '0' }));
|
|
434
|
+
} else {
|
|
435
|
+
chunks.push(gnuLongName(e.name));
|
|
436
|
+
chunks.push(ustarHeader({ name: e.name.slice(0, 100), mode, size: e.buf.length, typeflag: '0' }));
|
|
437
|
+
}
|
|
438
|
+
chunks.push(padTo512(e.buf));
|
|
439
|
+
}
|
|
440
|
+
// two zero blocks terminate the archive
|
|
441
|
+
chunks.push(Buffer.alloc(1024, 0));
|
|
442
|
+
const tar = Buffer.concat(chunks);
|
|
443
|
+
return zlib.gzipSync(tar, { level: 9 });
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// ---- git plumbing (impure) ------------------------------------------------
|
|
447
|
+
function git(args) {
|
|
448
|
+
return execFileSync('git', ['-C', REPO_ROOT, ...args], { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });
|
|
449
|
+
}
|
|
450
|
+
function gitBuf(args) {
|
|
451
|
+
return execFileSync('git', ['-C', REPO_ROOT, ...args], { maxBuffer: 256 * 1024 * 1024 });
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
function arg(name, fallback = null) {
|
|
455
|
+
const i = process.argv.indexOf(name);
|
|
456
|
+
return i >= 0 && i + 1 < process.argv.length ? process.argv[i + 1] : fallback;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// npm is `npm.cmd` on Windows and can't be execFile'd bare; unix uses `npm`.
|
|
460
|
+
const NPM_BIN = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
461
|
+
|
|
462
|
+
// Pure — the exact `npm publish` argv for the built core tarball. Scoped packages
|
|
463
|
+
// publish PRIVATE via publishConfig.access:"restricted" (buildPackageJson); we ALSO
|
|
464
|
+
// pass `--access restricted` so a stray `publishConfig` edit can't silently make the
|
|
465
|
+
// pre-launch artifact public. `--dry-run` unless `live` (the permanent owner step).
|
|
466
|
+
function publishArgs(tgzPath, live) {
|
|
467
|
+
const a = ['publish', tgzPath, '--access', 'restricted'];
|
|
468
|
+
if (!live) a.push('--dry-run');
|
|
469
|
+
return a;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// Publish (or dry-run) the built .tgz to npm. Auth is npm's own concern — this
|
|
473
|
+
// never holds a token; it shells out to `npm publish` and the owner's `npm login`
|
|
474
|
+
// (+ the cloudbongos org on a paid plan, for a PRIVATE scoped publish) provides it.
|
|
475
|
+
// The child's stdout is routed to OUR stderr so main()'s machine-readable pin on
|
|
476
|
+
// stdout stays clean for CI capture.
|
|
477
|
+
function publishTarball({ tgzPath, live }) {
|
|
478
|
+
const args = publishArgs(tgzPath, live);
|
|
479
|
+
console.error('');
|
|
480
|
+
console.error(`[package-core] ${live ? 'PUBLISH (permanent)' : 'publish DRY-RUN'} → ${NPM_BIN} ${args.join(' ')}`);
|
|
481
|
+
if (!live) {
|
|
482
|
+
console.error(' Dry-run: nothing is uploaded. To publish for real: re-run with --publish --live.');
|
|
483
|
+
console.error(' That is PERMANENT and requires `npm login` + the cloudbongos npm org on a paid plan');
|
|
484
|
+
console.error(' (private scoped publish needs one). Going public later: `npm access public @cloudbongos/core`.');
|
|
485
|
+
}
|
|
486
|
+
const r = spawnSync(NPM_BIN, args, { cwd: REPO_ROOT, stdio: ['inherit', process.stderr, 'inherit'] });
|
|
487
|
+
if (r.error || r.status !== 0) {
|
|
488
|
+
console.error(`[package-core] npm publish ${live ? '' : '--dry-run '}FAILED (${r.error ? r.error.message : `exit ${r.status}`}).`);
|
|
489
|
+
if (live) console.error(' Common causes: not logged in (`npm login`), the org isn’t on a paid plan (private scoped publish requires one), or 2FA.');
|
|
490
|
+
process.exit(r.status || 1);
|
|
491
|
+
}
|
|
492
|
+
console.error(`[package-core] npm publish ${live ? 'succeeded — @cloudbongos/core is live (private).' : 'dry-run OK — the tarball is publishable.'}`);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
function main() {
|
|
496
|
+
const ref = arg('--ref', 'HEAD');
|
|
497
|
+
const outDir = path.resolve(REPO_ROOT, arg('--out-dir', 'dist'));
|
|
498
|
+
const version = arg('--version', coreVersion());
|
|
499
|
+
const contract = coreVersion();
|
|
500
|
+
const dropletIp = arg('--droplet-ip', process.env.DROPLET_IP || null);
|
|
501
|
+
|
|
502
|
+
// 1. Resolve the source ref → commit SHA (the lineage anchor of this artifact).
|
|
503
|
+
let sha;
|
|
504
|
+
try { sha = git(['rev-parse', ref]).trim(); }
|
|
505
|
+
catch (e) { console.error(`refusing: could not resolve --ref "${ref}": ${e.message}`); process.exit(2); }
|
|
506
|
+
|
|
507
|
+
// 2. Enumerate + partition the tree through the manifest (single source of truth).
|
|
508
|
+
// package.json/package-lock.json are SYNTHESIZED (task 1882, ADR 0108 §2) —
|
|
509
|
+
// isPublishable() still selects them (they're not manifest-excluded, the mirror
|
|
510
|
+
// ships them verbatim), but the core package needs its OWN identity + a pruned
|
|
511
|
+
// dependency set, not the game's. Pulled out of the generic per-file loop below.
|
|
512
|
+
const SYNTHESIZED_PATHS = new Set(['package.json', 'package-lock.json']);
|
|
513
|
+
const entries = parseLsTree(git(['ls-tree', '-r', sha])).filter((e) => e.type === 'blob');
|
|
514
|
+
const publishable = entries.filter((e) => isPublishable(e.path) && !SYNTHESIZED_PATHS.has(e.path));
|
|
515
|
+
console.error(`[package-core] ${ref} = ${sha.slice(0, 12)} — ${entries.length} files, ${publishable.length} in the core (+2 synthesized), ${entries.length - publishable.length - 2} excluded.`);
|
|
516
|
+
if (publishable.length === 0) {
|
|
517
|
+
console.error('refusing: the core set is EMPTY — almost certainly a manifest/ref mismatch, not intentional. Aborting.');
|
|
518
|
+
process.exit(1);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// 2b. Synthesize the core's own package.json + pruned package-lock.json from the
|
|
522
|
+
// SOURCE files at this ref (never the live working tree, so --ref stays
|
|
523
|
+
// reproducible) — express+pg only, name @cloudbongos/core, version = the
|
|
524
|
+
// platform version being packaged.
|
|
525
|
+
const pkgJsonBlob = entries.find((e) => e.path === 'package.json');
|
|
526
|
+
const pkgLockBlob = entries.find((e) => e.path === 'package-lock.json');
|
|
527
|
+
if (!pkgJsonBlob || !pkgLockBlob) {
|
|
528
|
+
console.error('refusing: source package.json/package-lock.json not found at this ref — cannot synthesize the core package.');
|
|
529
|
+
process.exit(1);
|
|
530
|
+
}
|
|
531
|
+
const sourcePkgJson = JSON.parse(gitBuf(['cat-file', 'blob', pkgJsonBlob.sha]).toString('utf8'));
|
|
532
|
+
const sourcePkgLock = JSON.parse(gitBuf(['cat-file', 'blob', pkgLockBlob.sha]).toString('utf8'));
|
|
533
|
+
const corePkgJson = buildPackageJson({ version, sourceDeps: sourcePkgJson.dependencies, sourceOverrides: sourcePkgJson.overrides });
|
|
534
|
+
const corePkgLock = prunePackageLock(sourcePkgLock, {
|
|
535
|
+
name: corePkgJson.name, version, rootRanges: { express: corePkgJson.dependencies.express, pg: corePkgJson.dependencies.pg },
|
|
536
|
+
});
|
|
537
|
+
console.error(`[package-core] synthesized package.json (${Object.keys(corePkgJson.dependencies).join(', ')}) + pruned package-lock.json (${Object.keys(corePkgLock.packages).length - 1} of ${Object.keys(sourcePkgLock.packages).length - 1} locked packages kept).`);
|
|
538
|
+
|
|
539
|
+
// 3. Redaction rules from THIS instance's branding (current HEAD) + the droplet
|
|
540
|
+
// IP as an exact extra literal (sourced here, never written into a file).
|
|
541
|
+
let branding = {};
|
|
542
|
+
try { branding = JSON.parse(fs.readFileSync(path.join(REPO_ROOT, 'config/branding.json'), 'utf8')); }
|
|
543
|
+
catch { /* vanilla instance: derive from the public-IP floor only */ }
|
|
544
|
+
const ownerAliases = String(process.env.OWNER_ALIASES || '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
545
|
+
const extra = { owners: ownerAliases, literals: dropletIp ? [dropletIp] : [] };
|
|
546
|
+
const rules = buildRedactionRules(branding, extra);
|
|
547
|
+
const sensitiveLiterals = collectSensitiveLiterals(branding, extra);
|
|
548
|
+
const envSecrets = collectEnvSecrets();
|
|
549
|
+
console.error(`[package-core] ${rules.length} redaction rule(s), ${sensitiveLiterals.length} gate literal(s) + public-IP floor + ${envSecrets.length} env-secret literal(s).`);
|
|
550
|
+
|
|
551
|
+
// 4. Process every file IN MEMORY (processCoreFile: docs redacted, functional verbatim)
|
|
552
|
+
// + the fail-closed no-leak gate. Nothing touches dist/ until the ENTIRE set is proven
|
|
553
|
+
// clean (atomic abort). Brand/topology in functional files are non-fatal ADVISORIES.
|
|
554
|
+
const staged = []; // { name, mode, buf } (name includes TAR_ROOT)
|
|
555
|
+
const filesMeta = []; // { path, mode, sha256 } (source files only — the pin domain)
|
|
556
|
+
const leaks = [];
|
|
557
|
+
const advisories = []; // { path, label, sample } — non-fatal (brand/IP that ships verbatim)
|
|
558
|
+
let docCount = 0;
|
|
559
|
+
let funcCount = 0;
|
|
560
|
+
for (const e of publishable) {
|
|
561
|
+
let raw;
|
|
562
|
+
try { raw = gitBuf(['cat-file', 'blob', e.sha]); }
|
|
563
|
+
catch (err) { leaks.push({ path: e.path, label: `read-failed:${err.message}` }); continue; }
|
|
564
|
+
const { buf, leaks: fileLeaks, advisories: fileAdvisories, kind } =
|
|
565
|
+
processCoreFile({ pathRel: e.path, raw, rules, sensitiveLiterals, envSecrets });
|
|
566
|
+
for (const l of fileLeaks) leaks.push({ path: e.path, label: l.label, sample: l.sample });
|
|
567
|
+
for (const a of fileAdvisories) advisories.push({ path: e.path, label: a.label, sample: a.sample });
|
|
568
|
+
if (kind === 'doc') docCount++; else funcCount++;
|
|
569
|
+
filesMeta.push({ path: e.path, mode: e.mode, sha256: sha256hex(buf) });
|
|
570
|
+
staged.push({ name: TAR_ROOT + e.path, mode: parseInt(normalizeMode(e.mode), 8), buf });
|
|
571
|
+
}
|
|
572
|
+
funcCount += 2; // the two synthesized files below, staged outside the leak-gated loop
|
|
573
|
+
|
|
574
|
+
// The two synthesized files (2b above) carry no source content — no OTB brand,
|
|
575
|
+
// no secrets — so they need no redaction/leak scan; stage them directly into
|
|
576
|
+
// the same filesMeta/staged arrays the pin + tarball are built from.
|
|
577
|
+
for (const [relPath, obj] of [['package.json', corePkgJson], ['package-lock.json', corePkgLock]]) {
|
|
578
|
+
const buf = Buffer.from(`${JSON.stringify(obj, null, 2)}\n`, 'utf8');
|
|
579
|
+
filesMeta.push({ path: relPath, mode: '100644', sha256: sha256hex(buf) });
|
|
580
|
+
staged.push({ name: TAR_ROOT + relPath, mode: 0o644, buf });
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
if (leaks.length > 0) {
|
|
584
|
+
console.error(`\n[package-core] NO-LEAK GATE FAILED — ${leaks.length} real leak(s) (doc redaction residue or a live credential in a functional file). PRODUCING NOTHING (fail-closed):`);
|
|
585
|
+
for (const l of leaks.slice(0, 50)) {
|
|
586
|
+
// Never print a secret sample; a redaction-residue instance literal is safe to show.
|
|
587
|
+
const shown = (l.label === 'live-credential' || l.label === 'doc:secret-shape')
|
|
588
|
+
? '' : (l.sample ? ` (“${String(l.sample).slice(0, 40)}”)` : '');
|
|
589
|
+
console.error(` ${l.path}: ${l.label}${shown}`);
|
|
590
|
+
}
|
|
591
|
+
if (leaks.length > 50) console.error(` … +${leaks.length - 50} more`);
|
|
592
|
+
console.error('\nFix: for a DOC leak, extend scripts/gds/mirror-redact.js (rules) or scripts/gds/publish-manifest.js (exclusions);');
|
|
593
|
+
console.error(' for a live-credential leak, remove the secret at SOURCE (it should never be committed). Then re-run. dist/ was NOT touched.');
|
|
594
|
+
process.exit(1);
|
|
595
|
+
}
|
|
596
|
+
console.error(`[package-core] no-leak gate PASSED — ${staged.length} files clean (${docCount} docs redacted, ${funcCount} functional verbatim).`);
|
|
597
|
+
|
|
598
|
+
// Advisory: brand-identity + public-IP literals that ship VERBATIM inside functional
|
|
599
|
+
// files. Not a leak (these are public, not secrets; a downstream rebrands via config) —
|
|
600
|
+
// surfaced so a human can see what instance-specific strings the consumer core carries.
|
|
601
|
+
if (advisories.length > 0) {
|
|
602
|
+
const byLabel = {};
|
|
603
|
+
for (const a of advisories) { const k = a.sample || a.label; byLabel[k] = (byLabel[k] || 0) + 1; }
|
|
604
|
+
const summary = Object.entries(byLabel).sort((x, y) => y[1] - x[1]).map(([k, n]) => `${k}×${n}`).join(', ');
|
|
605
|
+
console.error(`[package-core] advisory — ${advisories.length} brand/topology string(s) ship verbatim in functional files (public, not secrets): ${summary}.`);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// 5. Build the pin manifest, then materialize dist/ (only reached when clean).
|
|
609
|
+
filesMeta.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
|
|
610
|
+
const treeHash = canonicalTreeHash(filesMeta);
|
|
611
|
+
const innerManifest = buildCoreManifest({
|
|
612
|
+
version, coreContract: contract, sourceCommit: sha, sourceRef: ref,
|
|
613
|
+
builtAtIso: new Date().toISOString(), files: filesMeta, treeHash,
|
|
614
|
+
redaction: {
|
|
615
|
+
model: 'docs-redacted+functional-verbatim', // task 1824
|
|
616
|
+
docs_redacted: docCount,
|
|
617
|
+
functional_verbatim: funcCount,
|
|
618
|
+
rules: rules.length,
|
|
619
|
+
gate_literals: sensitiveLiterals.length,
|
|
620
|
+
gate: 'passed',
|
|
621
|
+
},
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
// The self-describing manifest travels INSIDE the artifact too (minus tarball.*).
|
|
625
|
+
const innerJson = Buffer.from(JSON.stringify(innerManifest, null, 2) + '\n', 'utf8');
|
|
626
|
+
staged.push({ name: INNER_MANIFEST, mode: 0o644, buf: innerJson });
|
|
627
|
+
|
|
628
|
+
const tgz = buildTar(staged);
|
|
629
|
+
const sidecar = withTarballInfo(innerManifest, {
|
|
630
|
+
name: tarballName(version), sha256: sha256hex(tgz), bytes: tgz.length,
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
// Write: a fresh versioned stage dir (inspectable tree) + the .tgz + the pin.
|
|
634
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
635
|
+
const stageDir = path.join(outDir, stageDirName(version));
|
|
636
|
+
fs.rmSync(stageDir, { recursive: true, force: true });
|
|
637
|
+
for (const f of staged) {
|
|
638
|
+
// strip the TAR_ROOT prefix for the on-disk tree
|
|
639
|
+
const rel = f.name.startsWith(TAR_ROOT) ? f.name.slice(TAR_ROOT.length) : f.name;
|
|
640
|
+
const dest = path.join(stageDir, rel);
|
|
641
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
642
|
+
fs.writeFileSync(dest, f.buf, { mode: f.mode });
|
|
643
|
+
}
|
|
644
|
+
const tgzPath = path.join(outDir, tarballName(version));
|
|
645
|
+
const manifestPath = path.join(outDir, manifestName(version));
|
|
646
|
+
fs.writeFileSync(tgzPath, tgz);
|
|
647
|
+
fs.writeFileSync(manifestPath, JSON.stringify(sidecar, null, 2) + '\n');
|
|
648
|
+
|
|
649
|
+
console.error('');
|
|
650
|
+
console.error(`[package-core] Cloud Bongos core v${version} packaged (contract ^${contract}).`);
|
|
651
|
+
console.error(` source_commit ${sha}`);
|
|
652
|
+
console.error(` file_count ${filesMeta.length}`);
|
|
653
|
+
console.error(` tree_sha256 ${treeHash}`);
|
|
654
|
+
console.error(` tarball ${path.relative(REPO_ROOT, tgzPath)} (${(tgz.length / 1024).toFixed(1)} KiB, sha256 ${sidecar.tarball.sha256.slice(0, 12)}…)`);
|
|
655
|
+
console.error(` manifest ${path.relative(REPO_ROOT, manifestPath)} ← the PIN a downstream repo records`);
|
|
656
|
+
console.error(` tree ${path.relative(REPO_ROOT, stageDir)}/`);
|
|
657
|
+
|
|
658
|
+
// Optional publish leg (task 2089): --publish runs `npm publish` on the built
|
|
659
|
+
// tarball. DRY-RUN by default; the real, permanent publish needs --publish --live
|
|
660
|
+
// (+ npm auth). Kept AFTER the artifact is written so a publish failure never
|
|
661
|
+
// costs the build; runs BEFORE the stdout pin so that pin stays the last line out.
|
|
662
|
+
if (process.argv.includes('--publish')) {
|
|
663
|
+
publishTarball({ tgzPath, live: process.argv.includes('--live') });
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// stdout carries the machine-readable pin (so CI / R85 can capture it).
|
|
667
|
+
process.stdout.write(JSON.stringify({ core_version: version, source_commit: sha, tree_sha256: treeHash, tarball: sidecar.tarball }) + '\n');
|
|
668
|
+
process.exit(0);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
module.exports = {
|
|
672
|
+
MANIFEST_SCHEMA, ARTIFACT_NAME, TAR_ROOT, INNER_MANIFEST,
|
|
673
|
+
coreVersion, sha256hex, canonicalTreeHash, normalizeMode,
|
|
674
|
+
buildCoreManifest, withTarballInfo, tarballName, manifestName, stageDirName,
|
|
675
|
+
octal, tarChecksum, ustarHeader, splitUstarName, buildTar,
|
|
676
|
+
// task 1824 — the consumer-core file-classification layer (pure; unit-tested)
|
|
677
|
+
isDocPath, functionalSecretLeaks, processCoreFile,
|
|
678
|
+
// task 1882 (ADR 0108 §2) — the real installable npm package
|
|
679
|
+
CORE_DEP_NAMES, buildPackageJson, resolveLockDep, lockfileClosure, prunePackageLock,
|
|
680
|
+
// task 2089 (ADR 0134) — private-by-default npm publish
|
|
681
|
+
publishArgs,
|
|
682
|
+
};
|
|
683
|
+
|
|
684
|
+
if (require.main === module) main();
|