@bongos/core 1.21.175 → 1.21.177
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 +3371 -1636
- package/.claude/skills/ask-for-help/SKILL.md +4 -4
- package/.claude/skills/backlog-review/SKILL.md +1 -1
- package/.claude/skills/blocker-review/SKILL.md +2 -2
- package/.claude/skills/blocker-solve/SKILL.md +4 -4
- package/.claude/skills/bongos-feedback/SKILL.md +1 -1
- package/.claude/skills/bug-triage/SKILL.md +8 -8
- package/.claude/skills/builder-backup/SKILL.md +3 -3
- package/.claude/skills/builder-claim/SKILL.md +5 -5
- package/.claude/skills/builder-cost/SKILL.md +5 -5
- package/.claude/skills/builder-end/SKILL.md +6 -6
- package/.claude/skills/builder-exit/SKILL.md +2 -2
- package/.claude/skills/builder-key/SKILL.md +6 -6
- package/.claude/skills/builder-reauth/SKILL.md +4 -4
- package/.claude/skills/builder-redteam/SKILL.md +3 -3
- package/.claude/skills/builder-release/SKILL.md +3 -3
- package/.claude/skills/builder-sequence/SKILL.md +8 -8
- package/.claude/skills/builder-setup/SKILL.md +4 -4
- package/.claude/skills/builder-ship/SKILL.md +7 -7
- package/.claude/skills/builder-stage/SKILL.md +8 -8
- package/.claude/skills/builder-start/SKILL.md +4 -4
- package/.claude/skills/collab-review/SKILL.md +5 -5
- package/.claude/skills/design/SKILL.md +6 -4
- package/.claude/skills/design-sync/SKILL.md +3 -3
- package/.claude/skills/figma-design-sync/SKILL.md +4 -4
- package/.claude/skills/fix-task/SKILL.md +8 -8
- package/.claude/skills/goal-close/SKILL.md +9 -9
- package/.claude/skills/goal-create/SKILL.md +18 -18
- package/.claude/skills/grade-recover/SKILL.md +8 -8
- package/.claude/skills/grade-sweep/SKILL.md +15 -15
- package/.claude/skills/idea-triage/SKILL.md +15 -15
- package/.claude/skills/merge-mode/SKILL.md +14 -14
- package/.claude/skills/new-project/SKILL.md +5 -5
- package/.claude/skills/owner-review/SKILL.md +1 -1
- package/.claude/skills/planning-session/SKILL.md +15 -15
- package/.claude/skills/priority-session/SKILL.md +6 -6
- package/.claude/skills/read-session-export/SKILL.md +3 -3
- package/.claude/skills/recall/SKILL.md +7 -7
- package/.claude/skills/scan-before-install/SKILL.md +3 -3
- package/.claude/skills/session-handoff/SKILL.md +1 -1
- package/.claude/skills/ship-check/SKILL.md +3 -3
- package/.claude/skills/status/SKILL.md +3 -3
- package/.claude/skills/strand-fix/SKILL.md +6 -6
- package/.claude/skills/worktree-clean/SKILL.md +4 -4
- package/.gitattributes +12 -32
- package/GOVERNMENT.md +1 -1
- package/README.md +8 -8
- package/bin/bongos.js +23 -23
- package/clients/bongos-client/README.md +2 -2
- package/clients/bongos-client/bongos-client.global.js +22 -4
- package/clients/bongos-client/index.cjs +22 -4
- package/clients/bongos-client/index.d.ts +33 -4
- package/clients/bongos-client/index.mjs +21 -3
- package/config/branding.neutral.json +1 -1
- package/config/design-tokens.schema.json +1 -1
- package/config/modules.neutral.json +1 -3
- package/config/scheduled-routines.json +3 -8
- package/docs/adr/0029-status-page-outage-resilience.md +6 -6
- package/docs/adr/0091-bounding-the-kernel-and-db-carve.md +1 -1
- package/docs/adr/0093-tranche-2-core-carve-sequence.md +1 -1
- package/docs/adr/0227-a-task-network-map-is-refused-the-goal-graph-is-the-map.md +1 -1
- package/docs/adr/0294-cli-sessions-do-not-expire.md +1 -1
- package/docs/adr/0383-sessions-end-after-ten-idle-days.md +35 -0
- package/docs/adr/0384-the-raise-page-is-a-hub-module-builders-edit-in-place.md +31 -0
- package/docs/adr/README.md +2 -0
- package/docs/api/openapi.json +606 -44
- package/docs/api-reference.md +25 -12
- package/docs/architecture.md +8 -7
- package/docs/canonical-permissions.md +4 -4
- package/docs/copy-inventory.md +1370 -1411
- package/docs/copy-registry.json +2136 -2536
- package/docs/design/demonolith-plan.md +6 -6
- package/docs/design/modular-architecture/00-research-report.md +1 -1
- package/docs/design/project-startup-direction.md +2 -2
- package/docs/design/projects-hub-direction-v2.md +1 -1
- package/docs/design/reviews/hall-v2/README.md +2 -2
- package/docs/design/vanilla-hall-ui-redesign-scope.md +1 -1
- package/docs/file-map.md +92 -96
- package/docs/handoff-template.md +5 -5
- package/docs/module-api-changelog.md +7 -3
- package/docs/modules-contract.md +8 -7
- package/docs/onboarding/diagrams/01-task-lifecycle.mmd +1 -1
- package/docs/onboarding/diagrams/02-rank-ladder.mmd +1 -1
- package/docs/onboarding/diagrams/03-drachmae-karma.mmd +1 -1
- package/docs/onboarding/diagrams/04-architecture.mmd +1 -1
- package/docs/onboarding/diagrams/05-versioning.mmd +1 -1
- package/docs/onboarding/diagrams/README.md +5 -9
- package/docs/onboarding/diagrams/assertions.json +3 -3
- package/docs/onboarding/slash-commands.md +2 -2
- package/docs/packs/artist.md +4 -4
- package/docs/packs/engineer.md +11 -10
- package/docs/packs/ideator.md +7 -7
- package/docs/page-inventory.json +20 -1
- package/docs/page-readings.json +4387 -4603
- package/docs/recipes/README.md +1 -1
- package/docs/recipes/audit-replay.md +4 -4
- package/docs/recipes/autobongos-windows-host.md +6 -6
- package/docs/recipes/bongos-cli-release.md +2 -2
- package/docs/recipes/claude-design-loop.md +7 -7
- package/docs/recipes/core-release-pipeline.md +19 -19
- package/docs/recipes/failed-ship-recovery-proof.md +2 -2
- package/docs/recipes/figma-design-loop.md +6 -6
- package/docs/recipes/gds-db-backup.md +9 -9
- package/docs/recipes/instance-deploy.md +3 -3
- package/docs/recipes/instance-first-run.md +1 -1
- package/docs/recipes/multi-builder-merge.md +2 -2
- package/docs/recipes/ops-gotchas.md +13 -10
- package/docs/recipes/packaging-the-core.md +6 -6
- package/docs/recipes/parallel-goal-waves.md +4 -4
- package/docs/recipes/private-npm-distribution.md +9 -9
- package/docs/recipes/redteam-patrol.md +5 -5
- package/docs/recipes/render-pilot.md +2 -2
- package/docs/recipes/reranking-a-goals-board.md +2 -2
- package/docs/recipes/search-index-ingestion.md +5 -5
- package/docs/recipes/self-host.md +1 -1
- package/docs/recipes/ship-and-regrade.md +4 -4
- package/docs/recipes/staging-environment.md +1 -1
- package/docs/recipes/standalone-live-docs.md +1 -1
- package/docs/recipes/ui-look-before-you-ship.md +2 -2
- package/docs/recipes/upgrading-the-core.md +11 -11
- package/docs/recipes/windows-builders.md +18 -18
- package/docs/research/llm-model-agnostic-and-cheaper-grader.md +6 -6
- package/docs/research/task-network-map-readability.md +3 -3
- package/migrations/core_278_builder_tester_tag.sql +18 -0
- package/migrations/core_279_bongos_shipper_new_scripts_path.sql +13 -0
- package/modules/agents/lib/answer-hold.js +1 -1
- package/modules/agents/lib/gate.js +1 -1
- package/modules/agents/lib/validate.js +1 -1
- package/modules/autonomy/db.js +9 -0
- package/modules/autonomy/gauge.js +1 -1
- package/modules/autonomy/governor-docket.js +2 -2
- package/modules/autonomy/module.json +2 -2
- package/modules/autonomy/pollers/daily-checks.js +262 -0
- package/modules/autonomy/pollers/routine-timers.js +9 -7
- package/modules/autonomy/rank-roles.js +64 -0
- package/modules/autonomy/routes/autonomy.js +3 -3
- package/modules/autonomy/server-schedule.js +37 -0
- package/modules/builder-settings/interaction-prefs.js +1 -1
- package/modules/builder-settings/render-prefs.js +1 -1
- package/modules/builder-settings/routes/settings.js +1 -1
- package/modules/builder-settings/skill-prefs.js +2 -2
- package/modules/builder-settings/wandering-prefs.js +2 -2
- package/modules/copy-desk/module.json +2 -2
- package/modules/copy-desk/page-data.js +5 -5
- package/modules/copy-desk/page-decisions.js +13 -1
- package/modules/copy-desk/proposals.js +4 -4
- package/modules/copy-desk/registry.js +2 -2
- package/modules/copy-desk/routes/copy-desk-release.js +119 -0
- package/modules/copy-desk/routes/copy-desk.js +3 -12
- package/modules/copy-desk/skills/tweak/SKILL.md +12 -12
- package/modules/copy-desk/tests/copy_flags.mjs +1 -1
- package/modules/copy-desk/tests/copy_no_cms.mjs +7 -3
- package/modules/copy-desk/tests/copy_proposals.mjs +2 -2
- package/modules/copy-desk/tests/copy_queue.mjs +1 -1
- package/modules/design-styles/skills/README.md +4 -4
- package/modules/design-styles/skills/imagegen-frontend-mobile/SKILL.md +1 -1
- package/modules/design-styles/skills/imagegen-frontend-web/SKILL.md +1 -1
- package/modules/discord/bug-attachments.js +1 -1
- package/modules/discord/ship-broadcast.js +1 -1
- package/modules/economy/achievements.js +49 -7
- package/modules/economy/cost-classify.js +6 -6
- package/modules/economy/cost-report.js +1 -1
- package/modules/economy/cost.js +1 -1
- package/modules/economy/credits.js +2 -1
- package/modules/economy/idea-size.js +2 -2
- package/modules/economy/reward.js +2 -0
- package/modules/economy/routes/cost.js +1 -1
- package/modules/economy/streak.js +43 -4
- package/modules/government/asks.js +1 -1
- package/modules/government/board.js +19 -2
- package/modules/government/catalog.js +3 -0
- package/modules/government/migrations/government_033_idea_vote.sql +46 -0
- package/modules/government/protected-surfaces.json +48 -47
- package/modules/government/recommendations.js +6 -2
- package/modules/government/routes/government.js +1 -1
- package/modules/grading/generated-provenance.js +13 -5
- package/modules/grading/grade-engine.js +1 -1
- package/modules/grading/grader-rubric.json +1 -1
- package/modules/grading/grader-score.js +1 -1
- package/modules/grading/grader-workers/index.js +1 -1
- package/modules/grading/grader.js +1 -1
- package/modules/grading/routes/grade.js +1 -1
- package/modules/hall-ui/public/atlas.html +5 -7
- package/modules/hall-ui/public/atlas.js +1 -1
- package/modules/hall-ui/public/atlas.states.json +1 -1
- package/modules/hall-ui/public/blockers.css +9 -0
- package/modules/hall-ui/public/blockers.html +4 -4
- package/modules/hall-ui/public/blockers.js +29 -30
- package/modules/hall-ui/public/board-room.css +5 -17
- package/modules/hall-ui/public/board-room.html +5 -6
- package/modules/hall-ui/public/board-room.js +41 -23
- package/modules/hall-ui/public/board-room.states.json +1 -1
- package/modules/hall-ui/public/brand-apply.js +1 -1
- package/modules/hall-ui/public/brand-holes.js +1 -1
- package/modules/hall-ui/public/builders.js +40 -86
- package/modules/hall-ui/public/city-decide.js +18 -4
- package/modules/hall-ui/public/city.html +1 -1
- package/modules/hall-ui/public/collab.html +1 -1
- package/modules/hall-ui/public/commands.html +6 -9
- package/modules/hall-ui/public/copy-desk.html +1 -1
- package/modules/hall-ui/public/copy-desk.js +2 -2
- package/modules/hall-ui/public/craft-mode.js +4 -0
- package/modules/hall-ui/public/deploy.html +6 -2
- package/modules/hall-ui/public/deploy.js +21 -13
- package/modules/hall-ui/public/diagrams.css +1 -1
- package/modules/hall-ui/public/diagrams.html +5 -8
- package/modules/hall-ui/public/diagrams.states.json +1 -1
- package/modules/hall-ui/public/drachmae.html +3 -7
- package/modules/hall-ui/public/fleet.html +3 -2
- package/modules/hall-ui/public/fleet.js +0 -4
- package/modules/hall-ui/public/gate.html +7 -7
- package/modules/hall-ui/public/gate.js +58 -77
- package/modules/hall-ui/public/goal-map.html +1 -1
- package/modules/hall-ui/public/goals-page.js +5 -5
- package/modules/hall-ui/public/goals-render.js +10 -11
- package/modules/hall-ui/public/goals.css +10 -0
- package/modules/hall-ui/public/goals.html +14 -7
- package/modules/hall-ui/public/government.html +3 -5
- package/modules/hall-ui/public/government.js +1 -5
- package/modules/hall-ui/public/hall-render.js +117 -57
- package/modules/hall-ui/public/hall-widgets.js +11 -11
- package/modules/hall-ui/public/idea.html +1 -1
- package/modules/hall-ui/public/ideas.html +3 -1
- package/modules/hall-ui/public/ideas.js +1 -0
- package/modules/hall-ui/public/index.html +12 -6
- package/modules/hall-ui/public/index.states.json +1 -1
- package/modules/hall-ui/public/mine-lens.js +1 -1
- package/modules/hall-ui/public/modules.html +7 -10
- package/modules/hall-ui/public/modules.js +0 -2
- package/modules/hall-ui/public/my-agents.html +1 -1
- package/modules/hall-ui/public/palette.js +5 -5
- package/modules/hall-ui/public/primer.html +4 -9
- package/modules/hall-ui/public/profile-connections.js +10 -2
- package/modules/hall-ui/public/profile-roles.js +3 -10
- package/modules/hall-ui/public/profile.html +12 -10
- package/modules/hall-ui/public/profile.js +13 -17
- package/modules/hall-ui/public/project-settings.html +3 -4
- package/modules/hall-ui/public/project-settings.js +0 -3
- package/modules/hall-ui/public/ranks.html +5 -11
- package/modules/hall-ui/public/ranks.js +6 -8
- package/modules/hall-ui/public/roadmap.css +0 -2
- package/modules/hall-ui/public/roadmap.html +1 -1
- package/modules/hall-ui/public/roadmap.js +16 -51
- package/modules/hall-ui/public/roster.html +1 -1
- package/modules/hall-ui/public/sessions.html +6 -8
- package/modules/hall-ui/public/sessions.js +7 -7
- package/modules/hall-ui/public/settings.html +1 -1
- package/modules/hall-ui/public/shell-trail.js +1 -1
- package/modules/hall-ui/public/shell.js +17 -17
- package/modules/hall-ui/public/street-deck.css +2 -1
- package/modules/hall-ui/public/street-deck.js +10 -2
- package/modules/hall-ui/public/street-desk.js +16 -5
- package/modules/hall-ui/public/street.html +1 -1
- package/modules/hall-ui/public/studio-lib.js +4 -0
- package/modules/hall-ui/public/studio.css +2 -0
- package/modules/hall-ui/public/studio.html +1 -1
- package/modules/hall-ui/public/studio.js +27 -1
- package/modules/hall-ui/public/style.css +43 -26
- package/modules/hall-ui/public/task-detail.js +10 -7
- package/modules/hall-ui/public/task.css +2 -0
- package/modules/hall-ui/public/task.html +3 -1
- package/modules/hall-ui/public/task.js +23 -7
- package/modules/hall-ui/public/thinking.html +1 -1
- package/modules/hall-ui/public/tweak-editor.html +1 -1
- package/modules/hall-ui/public/vote-control.js +208 -0
- package/modules/hall-ui/public/watch.html +3 -5
- package/modules/hall-ui/public/watch.js +5 -4
- package/modules/hall-ui/public/welcome-boot.css +130 -0
- package/modules/hall-ui/public/welcome-boot.js +334 -0
- package/modules/hall-ui/public/welcome-day.webp +0 -0
- package/modules/hall-ui/public/welcome-night.webp +0 -0
- package/modules/hall-ui/public/work-summary.js +1 -1
- package/modules/hall-ui/public/work.css +1 -0
- package/modules/hall-ui/public/work.html +3 -1
- package/modules/hall-ui/public/work.js +2 -1
- package/modules/hall-ui/records/accomplishments.md +16 -0
- package/modules/hall-ui/records/hall-ask-card.md +9 -0
- package/modules/hall-ui/records/karma-vote-control.md +13 -0
- package/modules/hall-ui/records/oversight-family.md +1 -1
- package/modules/hall-ui/records/profile-connections.md +2 -0
- package/modules/hall-ui/records/profile-roles.md +1 -1
- package/modules/hall-ui/records/reading-rooms.md +1 -1
- package/modules/hall-ui/records/welcome-tower.md +50 -0
- package/modules/ideas/migrations/ideas_011_idea_votes.sql +31 -0
- package/modules/ideas/projection.js +1 -1
- package/modules/ideas/routes/blockers.js +3 -3
- package/modules/ideas/routes/inbox.js +29 -1
- package/modules/ideas/routes/ratify-goal.js +1 -1
- package/modules/ideas/routing.js +1 -1
- package/modules/ideas/templates.js +1 -1
- package/modules/ideas/trail-descent.js +1 -1
- package/modules/ideas/trail-size.js +1 -1
- package/modules/ideas/votes.js +93 -0
- package/modules/lifecycle/abandon-leftovers.js +1 -1
- package/modules/lifecycle/cascade.js +1 -1
- package/modules/lifecycle/conflict-resolve.js +13 -21
- package/modules/lifecycle/criterion-ref.js +1 -1
- package/modules/lifecycle/db-analytics.js +57 -4
- package/modules/lifecycle/db-deps-criteria.js +1 -1
- package/modules/lifecycle/db-ship.js +2 -2
- package/modules/lifecycle/db-tasks.js +2 -2
- package/modules/lifecycle/db-versions.js +1 -1
- package/modules/lifecycle/db.js +2 -0
- package/modules/lifecycle/dead-deps.js +3 -3
- package/modules/lifecycle/dependency-advisory.js +3 -3
- package/modules/lifecycle/goal-category.js +1 -1
- package/modules/lifecycle/goal-forest.js +1 -1
- package/modules/lifecycle/goal-task-relevance-advisory.js +1 -1
- package/modules/lifecycle/kickoff-checklist.js +1 -1
- package/modules/lifecycle/kickoff-seed.js +1 -1
- package/modules/lifecycle/lifecycle.js +2 -0
- package/modules/lifecycle/merge-reach.js +29 -15
- package/modules/lifecycle/missing-dep-classify.js +3 -3
- package/modules/lifecycle/module.json +2 -1
- package/modules/lifecycle/page-tweak-approve.js +85 -1
- package/modules/lifecycle/page-tweak-hold.js +1 -1
- package/modules/lifecycle/publish-reconciler.js +1 -2
- package/modules/lifecycle/rot.js +1 -1
- package/modules/lifecycle/routes/artist-gate.js +1 -1
- package/modules/lifecycle/routes/gate-approvals.js +22 -1
- package/modules/lifecycle/routes/goals.js +1 -1
- package/modules/lifecycle/routes/task-route-helpers.js +1 -1
- package/modules/lifecycle/routes/task-votes.js +54 -0
- package/modules/lifecycle/routes/task-write-routes.js +1 -1
- package/modules/lifecycle/routes/tasks.js +2 -2
- package/modules/lifecycle/routes/versions.js +2 -2
- package/modules/lifecycle/ship-card.js +4 -4
- package/modules/lifecycle/ship-preflight.js +1 -1
- package/modules/lifecycle/task-classifier.js +1 -1
- package/modules/lifecycle/task-status.js +1 -1
- package/modules/lifecycle/task-visual-db.js +1 -1
- package/modules/memory/learnings.js +1 -1
- package/modules/memory/pollers/search-index.js +2 -2
- package/modules/memory/routes/learnings.js +1 -1
- package/modules/memory/routes/memory.js +1 -1
- package/modules/memory/search.js +2 -2
- package/modules/npm-release/release.js +1 -1
- package/modules/onboarding/howto-moments.js +1 -1
- package/modules/onboarding/newcomer-restock.js +3 -3
- package/modules/onboarding/onboarding.js +1 -1
- package/modules/pixel-art/skills/otb-tile-generate/SKILL.md +1 -1
- package/modules/platform-identity/origin-containment.js +1 -1
- package/modules/platform-identity/publish-gate.js +1 -1
- package/modules/platform-identity/tests/platform-identity.mjs +1 -1
- package/modules/provisioning/capacity.js +1 -1
- package/modules/provisioning/core-upgrade.js +15 -9
- package/modules/provisioning/credential-preflight.js +3 -3
- package/modules/provisioning/disconnect.js +1 -1
- package/modules/provisioning/dns-resolves.js +1 -1
- package/modules/provisioning/module.json +1 -1
- package/modules/provisioning/onboard-plan.js +1 -1
- package/modules/provisioning/paid-shape-gate.js +2 -2
- package/modules/provisioning/planet-physics.js +11 -2
- package/modules/provisioning/pollers/liveness-sweep.js +1 -1
- package/modules/provisioning/pollers/runner-drift-notify.js +5 -5
- package/modules/provisioning/provisioning.js +2 -2
- package/modules/provisioning/render-lookup.js +1 -1
- package/modules/provisioning/render-standup.js +3 -3
- package/modules/provisioning/repo-private.js +1 -1
- package/modules/provisioning/routes/callback-page.js +1 -1
- package/modules/provisioning/routes/core-upgrade.js +23 -3
- package/modules/provisioning/routes/provisioning.js +2 -2
- package/modules/provisioning/routes/render-standup.js +1 -1
- package/modules/provisioning/routes/repo-private.js +1 -1
- package/modules/provisioning/soft-limits.js +1 -1
- package/modules/provisioning/starter-bundles.js +4 -2
- package/modules/provisioning/tests/provisioning.mjs +1 -1
- package/modules/public-landing/public/account.html +4 -6
- package/modules/public-landing/public/assets/cosmos.css +13 -6
- package/modules/public-landing/public/connections.html +4 -6
- package/modules/public-landing/public/contact.html +4 -6
- package/modules/public-landing/public/guild.html +4 -6
- package/modules/public-landing/public/index.html +11 -9
- package/modules/public-landing/public/invitations.html +4 -6
- package/modules/public-landing/public/privacy.html +4 -6
- package/modules/public-landing/public/projects.html +168 -46
- package/modules/public-landing/public/terms.html +4 -6
- package/modules/raise/content/copy.json +40 -0
- package/modules/raise/content/nda.html +39 -0
- package/modules/raise/content/settings.json +49 -0
- package/modules/raise/db.js +95 -0
- package/modules/raise/migrations/raise_001_tables.sql +71 -0
- package/modules/raise/module.json +28 -0
- package/modules/raise/page.js +194 -0
- package/modules/raise/public/edit.js +152 -0
- package/modules/raise/public/favicon.svg +1 -0
- package/modules/raise/public/logo-ink.svg +1 -0
- package/modules/raise/public/logo-night.svg +1 -0
- package/modules/raise/public/mode.js +8 -0
- package/modules/raise/public/raise.css +234 -0
- package/modules/raise/public/raise.js +91 -0
- package/modules/raise/raise.js +174 -0
- package/modules/raise/routes/raise.js +152 -0
- package/modules/raise/views/gate.html +39 -0
- package/modules/raise/views/nda.html +21 -0
- package/modules/raise/views/page.html +133 -0
- package/modules/raise/web.js +72 -0
- package/modules/render-deploy/deploys.js +1 -1
- package/modules/render-deploy/render.js +2 -2
- package/modules/security/secret-scrub.js +3 -3
- package/modules/security/security.js +1 -1
- package/modules/security/tests/artifact_scan.mjs +1 -1
- package/modules/security/tests/mirror.mjs +1 -1
- package/modules/security/tests/scan_store.mjs +1 -1
- package/modules/sessions/db.js +2 -2
- package/modules/sessions/pulse.js +2 -2
- package/modules/sessions/routes/sessions.js +1 -1
- package/modules/specialities/specialities.js +1 -1
- package/modules/status-ui/public/README.md +3 -4
- package/modules/status-ui/public/index.html +5 -31
- package/modules/status-ui/public/status.js +6 -174
- package/modules/status-ui/public/style.css +4 -133
- package/modules/ui-design/docs/design-contract.md +3 -3
- package/modules/ui-design/kit/README.md +1 -1
- package/modules/ui-design/kit/serve.js +13 -4
- package/modules/ui-design/scripts/design-sync.js +1 -1
- package/modules/ui-design/scripts/figma-design-sync.js +1 -1
- package/modules/ui-design/scripts/validate-design.js +1 -1
- package/package-lock.json +27 -11
- package/package.json +2 -3
- package/release-notes.json +186 -0
- package/scripts/bongos/CLAUDE.md +15 -0
- package/scripts/bongos/abandon.js +137 -0
- package/scripts/bongos/accessibility-replay.js +195 -0
- package/scripts/bongos/address-park-sweep.sh +91 -0
- package/scripts/bongos/adopt-detect.js +123 -0
- package/scripts/bongos/adopt-import.js +111 -0
- package/scripts/bongos/adopt-preflight.js +187 -0
- package/scripts/bongos/adr-namespace.js +273 -0
- package/scripts/bongos/agent-invoke.js +689 -0
- package/scripts/bongos/agents-sync.js +502 -0
- package/scripts/bongos/api-alias-caller-scan.js +256 -0
- package/scripts/bongos/api-artifacts.js +91 -0
- package/scripts/bongos/api.js +86 -0
- package/scripts/bongos/api.ps1 +26 -0
- package/scripts/bongos/architect-audit.js +294 -0
- package/scripts/bongos/artifact-audit.js +326 -0
- package/scripts/bongos/artifact-format.js +203 -0
- package/scripts/bongos/ask.js +231 -0
- package/scripts/bongos/audit-authorship.sh +324 -0
- package/scripts/bongos/audit-deps.js +189 -0
- package/scripts/bongos/audit-gate.js +121 -0
- package/scripts/bongos/audit-rank-roles.js +131 -0
- package/scripts/bongos/audit-replay.sh +205 -0
- package/scripts/bongos/autobongos-digest.js +123 -0
- package/scripts/bongos/autobongos-grade-cap.js +187 -0
- package/scripts/bongos/autobongos-loop.js +210 -0
- package/scripts/bongos/autobongos-run.js +1361 -0
- package/scripts/bongos/autobongos-service.cmd +50 -0
- package/scripts/bongos/autobongos-service.ps1 +270 -0
- package/scripts/bongos/autobongos-tweak-lane.js +262 -0
- package/scripts/bongos/autobongos-verify.js +618 -0
- package/scripts/bongos/autonomy-gate.js +135 -0
- package/scripts/bongos/autonomy-gauge-statusline.js +124 -0
- package/scripts/bongos/autonomy-gauge.js +84 -0
- package/scripts/bongos/backfill-cost.js +176 -0
- package/scripts/bongos/backfill-disciplines.js +144 -0
- package/scripts/bongos/backfill-session-earnings.js +123 -0
- package/scripts/bongos/backfill-session-types.js +87 -0
- package/scripts/bongos/backfill-sessions.js +411 -0
- package/scripts/bongos/backfill-subagent-rewards.js +485 -0
- package/scripts/bongos/backfill-task-rewards.js +413 -0
- package/scripts/bongos/backlog-review.js +399 -0
- package/scripts/bongos/backup-dropin-sweep.sh +95 -0
- package/scripts/bongos/backup.js +116 -0
- package/scripts/bongos/baseline-staleness.js +217 -0
- package/scripts/bongos/bfg-principal-token.js +65 -0
- package/scripts/bongos/bug-attachment-audit.js +149 -0
- package/scripts/bongos/bug-attachment-recover.js +198 -0
- package/scripts/bongos/bug-triage.js +292 -0
- package/scripts/bongos/build-bongos.js +94 -0
- package/scripts/bongos/bump-version.js +221 -0
- package/scripts/bongos/capture.js +481 -0
- package/scripts/bongos/category-advisory-guard.js +206 -0
- package/scripts/bongos/ci-grade.js +82 -0
- package/scripts/bongos/claim-recall.js +112 -0
- package/scripts/bongos/claim.js +789 -0
- package/scripts/bongos/claude-materialize.js +1200 -0
- package/scripts/bongos/claude-md-template.js +142 -0
- package/scripts/bongos/cleanup-orphans.js +74 -0
- package/scripts/bongos/cli-lib.js +1226 -0
- package/scripts/bongos/client-baseurl-guard.js +116 -0
- package/scripts/bongos/codemod-rename-scripts-gds.js +380 -0
- package/scripts/bongos/conductor-dispatch.js +535 -0
- package/scripts/bongos/context-pack.js +326 -0
- package/scripts/bongos/control-manifest.js +199 -0
- package/scripts/bongos/copy-apply.js +758 -0
- package/scripts/bongos/copy-inventory.js +571 -0
- package/scripts/bongos/core-origin-follow.js +185 -0
- package/scripts/bongos/core-pin-sync.js +260 -0
- package/scripts/bongos/cost-report.js +63 -0
- package/scripts/bongos/cost.js +47 -0
- package/scripts/bongos/credential-presence.js +296 -0
- package/scripts/bongos/cutover-codemod.js +240 -0
- package/scripts/bongos/db-backup-nightly.sh +232 -0
- package/scripts/bongos/db-backup-offsite.sh +267 -0
- package/scripts/bongos/demote.js +45 -0
- package/scripts/bongos/deploy-divergence.js +454 -0
- package/scripts/bongos/deploy-main-audit-gate.sh +97 -0
- package/scripts/bongos/design-sync.js +12 -0
- package/scripts/bongos/dev-box-guard.js +166 -0
- package/scripts/bongos/dev-lib.js +722 -0
- package/scripts/bongos/dev.js +645 -0
- package/scripts/bongos/device-flow-help.js +72 -0
- package/scripts/bongos/diagnose-achievements.js +118 -0
- package/scripts/bongos/diagram-facts.js +355 -0
- package/scripts/bongos/discord-channels.js +77 -0
- package/scripts/bongos/do-api.js +109 -0
- package/scripts/bongos/doc-cli-guard.js +274 -0
- package/scripts/bongos/doc-comment-coverage.js +139 -0
- package/scripts/bongos/doc-control-claims.js +170 -0
- package/scripts/bongos/docs-entropy.js +453 -0
- package/scripts/bongos/doctor.js +493 -0
- package/scripts/bongos/enroll-control-plane.js +101 -0
- package/scripts/bongos/exec-path-guard.js +564 -0
- package/scripts/bongos/feedback-send.js +249 -0
- package/scripts/bongos/fetch-art-key.js +106 -0
- package/scripts/bongos/fetch-sound-prefs.js +126 -0
- package/scripts/bongos/figma-design-sync.js +11 -0
- package/scripts/bongos/find-untested.js +371 -0
- package/scripts/bongos/fitness-checks-error-envelope.js +134 -0
- package/scripts/bongos/fitness-checks-identity.js +332 -0
- package/scripts/bongos/fitness-checks-packaging.js +132 -0
- package/scripts/bongos/fitness-checks-route-pins.js +76 -0
- package/scripts/bongos/fitness-checks-vocabulary.js +392 -0
- package/scripts/bongos/fitness-checks-write-validation.js +157 -0
- package/scripts/bongos/fitness-lib.js +127 -0
- package/scripts/bongos/fitness-migration-contraction.js +50 -0
- package/scripts/bongos/fitness-ratchets.js +594 -0
- package/scripts/bongos/fitness.js +1498 -0
- package/scripts/bongos/forwarder.js +80 -0
- package/scripts/bongos/gate-review.js +330 -0
- package/scripts/bongos/gating.js +348 -0
- package/scripts/{gds → bongos}/gds-db-backup.service +6 -6
- package/scripts/{gds → bongos}/gds-db-backup.timer +4 -4
- package/scripts/{gds → bongos}/gds-db-offsite.service +4 -4
- package/scripts/{gds → bongos}/gds-db-offsite.timer +4 -4
- package/scripts/bongos/gds-literal-scan.js +196 -0
- package/scripts/bongos/gen-api-client.js +576 -0
- package/scripts/bongos/gen-api-docs.js +1111 -0
- package/scripts/bongos/gen-atlas.js +366 -0
- package/scripts/bongos/gen-diagrams.js +608 -0
- package/scripts/bongos/gen-file-map.js +337 -0
- package/scripts/bongos/gen-freshness.js +32 -0
- package/scripts/bongos/gen-interaction-posture.js +122 -0
- package/scripts/bongos/gen-repo-map.js +540 -0
- package/scripts/bongos/gen-role-responsibilities.js +134 -0
- package/scripts/bongos/gen-session-index.js +243 -0
- package/scripts/bongos/gen-sounds.js +176 -0
- package/scripts/bongos/git-merge-regen.js +254 -0
- package/scripts/bongos/go-live.js +1071 -0
- package/scripts/bongos/goal.js +272 -0
- package/scripts/bongos/government-walk.js +1477 -0
- package/scripts/bongos/grade-correlation-audit.js +310 -0
- package/scripts/bongos/grade-replay.js +237 -0
- package/scripts/bongos/grade-smoke.js +205 -0
- package/scripts/bongos/home-isolation-guard.js +126 -0
- package/scripts/bongos/hooks/pre-push.js +211 -0
- package/scripts/bongos/howto.js +145 -0
- package/scripts/bongos/http-api-client.js +81 -0
- package/scripts/bongos/identity-strip.js +75 -0
- package/scripts/bongos/init.js +1159 -0
- package/scripts/bongos/install-git-hooks.js +200 -0
- package/scripts/bongos/instance-apex.js +38 -0
- package/scripts/bongos/intent-retry.js +52 -0
- package/scripts/bongos/key-card.js +222 -0
- package/scripts/bongos/key-status.js +126 -0
- package/scripts/bongos/land-watch.js +201 -0
- package/scripts/bongos/leak-scan-allowlist.js +293 -0
- package/scripts/bongos/learning-capture.js +145 -0
- package/scripts/bongos/lib.sh +74 -0
- package/scripts/bongos/linkify-refs.js +655 -0
- package/scripts/bongos/lint-infra-exec.js +70 -0
- package/scripts/bongos/lint-migrations.js +102 -0
- package/scripts/bongos/lint-workflow-exec.js +63 -0
- package/scripts/bongos/local-preview-lib.js +128 -0
- package/scripts/bongos/local-preview.js +82 -0
- package/scripts/bongos/login.js +360 -0
- package/scripts/bongos/main-audit.js +625 -0
- package/scripts/bongos/me.js +97 -0
- package/scripts/bongos/memory-map.js +176 -0
- package/scripts/bongos/merge-lock.js +71 -0
- package/scripts/bongos/migration-namespace.js +313 -0
- package/scripts/bongos/mirror-lineage-check.js +343 -0
- package/scripts/bongos/mirror-redact.js +350 -0
- package/scripts/bongos/module-artifact.js +289 -0
- package/scripts/bongos/module-assess-docs.js +238 -0
- package/scripts/bongos/module-assess-installs.js +228 -0
- package/scripts/bongos/module-assess-score.js +111 -0
- package/scripts/bongos/module-assess-security.js +252 -0
- package/scripts/bongos/module-assess-tests.js +278 -0
- package/scripts/bongos/module-assess-version.js +92 -0
- package/scripts/bongos/module-error-report.js +148 -0
- package/scripts/{gds → bongos}/module-test-runner/README.md +3 -3
- package/scripts/{gds → bongos}/module-test-runner/module-tests.yml +2 -2
- package/scripts/bongos/module-test-runner.js +414 -0
- package/scripts/bongos/module.js +1376 -0
- package/scripts/bongos/move-escalation.js +141 -0
- package/scripts/{gds → bongos}/newcomer-floor.config.json +1 -1
- package/scripts/bongos/newcomer-floor.js +421 -0
- package/scripts/{gds → bongos}/newcomer-floor.templates.json +13 -13
- package/scripts/bongos/newcomer-floor.test.js +235 -0
- package/scripts/bongos/next-number.js +163 -0
- package/scripts/bongos/oauth-secret.js +202 -0
- package/scripts/bongos/onboard.js +267 -0
- package/scripts/bongos/onboarding-analyze.js +226 -0
- package/scripts/bongos/onboarding-config.js +179 -0
- package/scripts/bongos/onboarding-ship.js +92 -0
- package/scripts/bongos/pack-env-prefix.js +73 -0
- package/scripts/bongos/package-core.js +1200 -0
- package/scripts/bongos/page-inventory.js +348 -0
- package/scripts/bongos/page-reader.js +722 -0
- package/scripts/bongos/paste-token.js +212 -0
- package/scripts/bongos/plain-cards.js +351 -0
- package/scripts/bongos/portability-smoke-art.sh +85 -0
- package/scripts/bongos/portability-smoke-memory.sh +176 -0
- package/scripts/bongos/preflight.js +214 -0
- package/scripts/bongos/probe-cache.js +246 -0
- package/scripts/bongos/prove-strict-versioning.js +284 -0
- package/scripts/bongos/provision-auto-upgrade.js +162 -0
- package/scripts/bongos/provision-byo-host.js +68 -0
- package/scripts/bongos/provision-capacity.js +79 -0
- package/scripts/bongos/provision-caps.js +63 -0
- package/scripts/bongos/provision-config.js +233 -0
- package/scripts/bongos/provision-core-upgrade.js +1166 -0
- package/scripts/bongos/provision-disconnect.js +88 -0
- package/scripts/bongos/provision-github-setup.js +168 -0
- package/scripts/bongos/provision-net.js +357 -0
- package/scripts/bongos/provision-pin-key.js +176 -0
- package/scripts/bongos/provision-pin-replay.js +126 -0
- package/scripts/bongos/provision-process.js +170 -0
- package/scripts/bongos/provision-render.js +201 -0
- package/scripts/bongos/provision-repo-auth.js +164 -0
- package/scripts/bongos/provision-repo-private.js +98 -0
- package/scripts/bongos/provision-repo.js +1337 -0
- package/scripts/bongos/provision-teardown.js +106 -0
- package/scripts/bongos/provision-units.js +469 -0
- package/scripts/bongos/provision.js +1479 -0
- package/scripts/bongos/publish-credential-check.js +66 -0
- package/scripts/bongos/publish-integration-gate.js +142 -0
- package/scripts/bongos/publish-manifest.js +440 -0
- package/scripts/bongos/publish-watch.js +268 -0
- package/scripts/bongos/pulse.js +338 -0
- package/scripts/bongos/push-main.js +56 -0
- package/scripts/bongos/push-path-brief.js +100 -0
- package/scripts/bongos/read-session-export.js +359 -0
- package/scripts/bongos/reauth.js +155 -0
- package/scripts/bongos/recall.js +183 -0
- package/scripts/bongos/redteam-patrol.js +437 -0
- package/scripts/bongos/regen-instance-docs.js +47 -0
- package/scripts/bongos/release-core.js +80 -0
- package/scripts/bongos/release-notes.js +271 -0
- package/scripts/bongos/release.js +139 -0
- package/scripts/bongos/rename-history-check.js +369 -0
- package/scripts/bongos/rename-ledger-prose.js +482 -0
- package/scripts/bongos/render-api.js +197 -0
- package/scripts/bongos/render-check.js +206 -0
- package/scripts/bongos/render-ideas.js +226 -0
- package/scripts/bongos/render-payload.js +85 -0
- package/scripts/bongos/repo-metrics.js +363 -0
- package/scripts/bongos/review-sheet.js +108 -0
- package/scripts/bongos/role-pack-guard.js +142 -0
- package/scripts/bongos/route-shadow-guard.js +175 -0
- package/scripts/bongos/routine-schedule.js +318 -0
- package/scripts/bongos/run-routine.js +257 -0
- package/scripts/bongos/run-unit-tests.js +654 -0
- package/scripts/bongos/runner-drift.js +151 -0
- package/scripts/bongos/sandbox-stage.js +459 -0
- package/scripts/bongos/scope-map-guard.js +300 -0
- package/scripts/bongos/scope-roster-guard.js +118 -0
- package/scripts/bongos/seam-wiring-guard.js +275 -0
- package/scripts/bongos/search-ingest-db.js +288 -0
- package/scripts/bongos/search-ingest-md.js +269 -0
- package/scripts/bongos/seed-bongos-v1-idea-routing-tasks.js +152 -0
- package/scripts/bongos/seed-bv1-profiles-tasks.js +135 -0
- package/scripts/bongos/seed-bv2-ideator-surface-tasks.js +390 -0
- package/scripts/bongos/seed-staging.sh +117 -0
- package/scripts/bongos/seed-verify-criteria.js +124 -0
- package/scripts/bongos/sequence.js +597 -0
- package/scripts/bongos/session-cost.js +430 -0
- package/scripts/bongos/session-digest-build.js +293 -0
- package/scripts/bongos/session-digest.js +200 -0
- package/scripts/bongos/session-eval.js +631 -0
- package/scripts/bongos/session-transcript-build.js +155 -0
- package/scripts/bongos/session-transcript-upload.js +29 -0
- package/scripts/bongos/session.js +404 -0
- package/scripts/bongos/setup.js +646 -0
- package/scripts/bongos/ship-check.js +89 -0
- package/scripts/bongos/ship-deploy-target.js +393 -0
- package/scripts/bongos/ship-escalation.js +167 -0
- package/scripts/bongos/ship-finish.js +420 -0
- package/scripts/bongos/ship-flow.js +1217 -0
- package/scripts/bongos/ship-git.js +100 -0
- package/scripts/bongos/ship-grade-steps.js +547 -0
- package/scripts/bongos/ship-grade.js +426 -0
- package/scripts/bongos/ship-honesty.js +314 -0
- package/scripts/bongos/ship-io.js +139 -0
- package/scripts/bongos/ship-land.js +1130 -0
- package/scripts/bongos/ship-memory-sync.js +249 -0
- package/scripts/bongos/ship-merge-gate.js +225 -0
- package/scripts/bongos/ship-merge.js +466 -0
- package/scripts/bongos/ship-mode-ask.js +138 -0
- package/scripts/bongos/ship-mode-manual.js +54 -0
- package/scripts/bongos/ship-preflight-steps.js +399 -0
- package/scripts/bongos/ship-regen.js +291 -0
- package/scripts/bongos/ship-resume.js +201 -0
- package/scripts/bongos/ship-session-upload.js +313 -0
- package/scripts/bongos/ship-state.js +110 -0
- package/scripts/bongos/ship-surprise.js +84 -0
- package/scripts/bongos/ship-visual.js +75 -0
- package/scripts/bongos/ship.js +382 -0
- package/scripts/bongos/shipping-mode.js +71 -0
- package/scripts/bongos/skill-lint.js +250 -0
- package/scripts/bongos/skill-preflight.js +361 -0
- package/scripts/bongos/smoke-batch-claim.sh +238 -0
- package/scripts/bongos/smoke-batch-release.sh +316 -0
- package/scripts/bongos/smoke-claim-consistency.sh +222 -0
- package/scripts/bongos/smoke-dependencies.sh +143 -0
- package/scripts/bongos/smoke-gds.js +256 -0
- package/scripts/bongos/smoke-write.sh +275 -0
- package/scripts/bongos/source-text-test-scan.js +106 -0
- package/scripts/bongos/spark.js +294 -0
- package/scripts/bongos/stale-worktrees.js +212 -0
- package/scripts/bongos/start-goals.js +102 -0
- package/scripts/bongos/start.js +1090 -0
- package/scripts/bongos/status.js +545 -0
- package/scripts/bongos/strand-watch.js +315 -0
- package/scripts/bongos/stranded-rows.js +200 -0
- package/scripts/bongos/stray-unit-sweep.sh +71 -0
- package/scripts/bongos/surface.js +101 -0
- package/scripts/bongos/task.js +273 -0
- package/scripts/bongos/test-path-guard.js +99 -0
- package/scripts/bongos/triage.js +742 -0
- package/scripts/bongos/turn-end-sound.js +74 -0
- package/scripts/bongos/tweak-halt.js +70 -0
- package/scripts/bongos/tweak-renders.js +200 -0
- package/scripts/bongos/uat.js +120 -0
- package/scripts/bongos/ui-kit-transform.js +43 -0
- package/scripts/bongos/update-channel.js +512 -0
- package/scripts/bongos/update-sweep.js +829 -0
- package/scripts/bongos/upgrade-artist-gate.js +46 -0
- package/scripts/bongos/upgrade-commit-identity.js +32 -0
- package/scripts/bongos/upgrade-migrate.js +224 -0
- package/scripts/bongos/upgrade-operator.js +73 -0
- package/scripts/bongos/upgrade-outcome.js +174 -0
- package/scripts/bongos/upgrade.js +1499 -0
- package/scripts/bongos/validate-design.js +12 -0
- package/scripts/bongos/version-close.js +621 -0
- package/scripts/bongos/version-literal-guard.js +140 -0
- package/scripts/bongos/version-select.js +79 -0
- package/scripts/bongos/visual-review-nudge.js +39 -0
- package/scripts/bongos/wedge-remedy.js +174 -0
- package/scripts/bongos/worktree-claim-guard.js +130 -0
- package/scripts/bongos/worktree.js +449 -0
- package/scripts/discord/post.js +1 -1
- package/scripts/gds/README.md +9 -0
- package/scripts/gds/abandon.js +6 -136
- package/scripts/gds/accessibility-replay.js +5 -194
- package/scripts/gds/address-park-sweep.sh +7 -90
- package/scripts/gds/adopt-detect.js +5 -121
- package/scripts/gds/adopt-import.js +5 -109
- package/scripts/gds/adopt-preflight.js +5 -185
- package/scripts/gds/adr-namespace.js +5 -271
- package/scripts/gds/agent-invoke.js +5 -687
- package/scripts/gds/agents-sync.js +5 -500
- package/scripts/gds/api-alias-caller-scan.js +5 -255
- package/scripts/gds/api-artifacts.js +6 -0
- package/scripts/gds/api.js +6 -85
- package/scripts/gds/api.ps1 +8 -26
- package/scripts/gds/architect-audit.js +6 -293
- package/scripts/gds/artifact-audit.js +5 -324
- package/scripts/gds/artifact-format.js +6 -203
- package/scripts/gds/ask.js +5 -229
- package/scripts/gds/audit-authorship.sh +7 -328
- package/scripts/gds/audit-deps.js +6 -188
- package/scripts/gds/audit-gate.js +5 -119
- package/scripts/gds/audit-rank-roles.js +6 -171
- package/scripts/gds/audit-replay.sh +7 -204
- package/scripts/gds/autobongos-digest.js +5 -121
- package/scripts/gds/autobongos-grade-cap.js +5 -186
- package/scripts/gds/autobongos-loop.js +5 -208
- package/scripts/gds/autobongos-run.js +5 -1359
- package/scripts/gds/autobongos-service.cmd +8 -49
- package/scripts/gds/autobongos-service.ps1 +8 -270
- package/scripts/gds/autobongos-tweak-lane.js +5 -261
- package/scripts/gds/autobongos-verify.js +5 -616
- package/scripts/gds/autonomy-gate.js +5 -133
- package/scripts/gds/autonomy-gauge-statusline.js +5 -122
- package/scripts/gds/autonomy-gauge.js +5 -82
- package/scripts/gds/backfill-cost.js +6 -175
- package/scripts/gds/backfill-disciplines.js +5 -142
- package/scripts/gds/backfill-session-earnings.js +5 -121
- package/scripts/gds/backfill-session-types.js +5 -85
- package/scripts/gds/backfill-sessions.js +5 -409
- package/scripts/gds/backfill-subagent-rewards.js +5 -483
- package/scripts/gds/backfill-task-rewards.js +5 -411
- package/scripts/gds/backlog-review.js +6 -398
- package/scripts/gds/backup-dropin-sweep.sh +7 -94
- package/scripts/gds/backup.js +6 -115
- package/scripts/gds/baseline-staleness.js +5 -215
- package/scripts/gds/bfg-principal-token.js +6 -64
- package/scripts/gds/bug-attachment-audit.js +5 -147
- package/scripts/gds/bug-attachment-recover.js +5 -196
- package/scripts/gds/bug-triage.js +6 -291
- package/scripts/gds/build-bongos.js +5 -92
- package/scripts/gds/bump-version.js +5 -219
- package/scripts/gds/capture.js +6 -480
- package/scripts/gds/category-advisory-guard.js +5 -205
- package/scripts/gds/ci-grade.js +6 -81
- package/scripts/gds/claim-recall.js +6 -111
- package/scripts/gds/claim.js +6 -788
- package/scripts/gds/claude-materialize.js +5 -1198
- package/scripts/gds/claude-md-template.js +5 -140
- package/scripts/gds/cleanup-orphans.js +6 -73
- package/scripts/gds/cli-lib.js +6 -1204
- package/scripts/gds/client-baseurl-guard.js +5 -114
- package/scripts/gds/conductor-dispatch.js +6 -534
- package/scripts/gds/context-pack.js +6 -325
- package/scripts/gds/control-manifest.js +5 -197
- package/scripts/gds/copy-apply.js +5 -756
- package/scripts/gds/copy-inventory.js +5 -569
- package/scripts/gds/core-origin-follow.js +5 -184
- package/scripts/gds/core-pin-sync.js +5 -258
- package/scripts/gds/cost-report.js +6 -62
- package/scripts/gds/cost.js +6 -46
- package/scripts/gds/credential-presence.js +5 -294
- package/scripts/gds/cutover-codemod.js +5 -239
- package/scripts/gds/db-backup-nightly.sh +7 -231
- package/scripts/gds/db-backup-offsite.sh +7 -266
- package/scripts/gds/demote.js +6 -44
- package/scripts/gds/deploy-divergence.js +6 -445
- package/scripts/gds/deploy-main-audit-gate.sh +7 -96
- package/scripts/gds/design-sync.js +5 -10
- package/scripts/gds/dev-box-guard.js +5 -164
- package/scripts/gds/dev-lib.js +5 -721
- package/scripts/gds/dev.js +5 -643
- package/scripts/gds/device-flow-help.js +5 -70
- package/scripts/gds/diagnose-achievements.js +5 -116
- package/scripts/gds/diagram-facts.js +6 -355
- package/scripts/gds/discord-channels.js +5 -75
- package/scripts/gds/do-api.js +6 -109
- package/scripts/gds/doc-cli-guard.js +5 -266
- package/scripts/gds/doc-comment-coverage.js +5 -137
- package/scripts/gds/doc-control-claims.js +5 -166
- package/scripts/gds/docs-entropy.js +5 -443
- package/scripts/gds/doctor.js +6 -492
- package/scripts/gds/enroll-control-plane.js +5 -99
- package/scripts/gds/exec-path-guard.js +5 -562
- package/scripts/gds/feedback-send.js +5 -247
- package/scripts/gds/fetch-art-key.js +5 -104
- package/scripts/gds/fetch-sound-prefs.js +5 -124
- package/scripts/gds/figma-design-sync.js +5 -9
- package/scripts/gds/find-untested.js +5 -369
- package/scripts/gds/fitness-checks-error-envelope.js +5 -133
- package/scripts/gds/fitness-checks-identity.js +5 -342
- package/scripts/gds/fitness-checks-packaging.js +5 -131
- package/scripts/gds/fitness-checks-route-pins.js +5 -75
- package/scripts/gds/fitness-checks-vocabulary.js +5 -391
- package/scripts/gds/fitness-checks-write-validation.js +5 -156
- package/scripts/gds/fitness-lib.js +5 -126
- package/scripts/gds/fitness-migration-contraction.js +5 -49
- package/scripts/gds/fitness-ratchets.js +5 -563
- package/scripts/gds/fitness.js +5 -1493
- package/scripts/gds/gate-review.js +5 -328
- package/scripts/gds/gating.js +5 -346
- package/scripts/gds/gds-literal-scan.js +5 -194
- package/scripts/gds/gen-api-client.js +5 -555
- package/scripts/gds/gen-api-docs.js +5 -1100
- package/scripts/gds/gen-atlas.js +5 -364
- package/scripts/gds/gen-diagrams.js +6 -607
- package/scripts/gds/gen-file-map.js +5 -335
- package/scripts/gds/gen-freshness.js +5 -31
- package/scripts/gds/gen-interaction-posture.js +5 -120
- package/scripts/gds/gen-repo-map.js +5 -538
- package/scripts/gds/gen-role-responsibilities.js +5 -133
- package/scripts/gds/gen-session-index.js +5 -241
- package/scripts/gds/gen-sounds.js +5 -174
- package/scripts/gds/git-merge-regen.js +6 -291
- package/scripts/gds/go-live.js +5 -1069
- package/scripts/gds/goal.js +6 -271
- package/scripts/gds/government-walk.js +5 -1475
- package/scripts/gds/grade-correlation-audit.js +5 -308
- package/scripts/gds/grade-replay.js +5 -235
- package/scripts/gds/grade-smoke.js +6 -204
- package/scripts/gds/home-isolation-guard.js +5 -125
- package/scripts/gds/hooks/pre-push.js +5 -209
- package/scripts/gds/howto.js +5 -143
- package/scripts/gds/http-api-client.js +6 -81
- package/scripts/gds/identity-strip.js +5 -74
- package/scripts/gds/init.js +5 -1157
- package/scripts/gds/install-git-hooks.js +5 -198
- package/scripts/gds/instance-apex.js +5 -37
- package/scripts/gds/intent-retry.js +5 -51
- package/scripts/gds/key-card.js +6 -221
- package/scripts/gds/key-status.js +5 -124
- package/scripts/gds/land-watch.js +5 -199
- package/scripts/gds/leak-scan-allowlist.js +5 -291
- package/scripts/gds/learning-capture.js +6 -144
- package/scripts/gds/lib.sh +7 -73
- package/scripts/gds/linkify-refs.js +6 -654
- package/scripts/gds/lint-infra-exec.js +5 -68
- package/scripts/gds/lint-migrations.js +5 -100
- package/scripts/gds/lint-workflow-exec.js +5 -61
- package/scripts/gds/local-preview-lib.js +6 -128
- package/scripts/gds/local-preview.js +6 -81
- package/scripts/gds/login.js +5 -358
- package/scripts/gds/main-audit.js +5 -623
- package/scripts/gds/me.js +6 -96
- package/scripts/gds/memory-map.js +5 -174
- package/scripts/gds/merge-lock.js +6 -70
- package/scripts/gds/migration-namespace.js +5 -311
- package/scripts/gds/mirror-lineage-check.js +5 -341
- package/scripts/gds/mirror-redact.js +5 -348
- package/scripts/gds/module-artifact.js +6 -289
- package/scripts/gds/module-assess-docs.js +6 -237
- package/scripts/gds/module-assess-installs.js +6 -227
- package/scripts/gds/module-assess-score.js +6 -110
- package/scripts/gds/module-assess-security.js +6 -251
- package/scripts/gds/module-assess-tests.js +6 -277
- package/scripts/gds/module-assess-version.js +6 -91
- package/scripts/gds/module-error-report.js +5 -146
- package/scripts/gds/module-test-runner.js +6 -413
- package/scripts/gds/module.js +5 -1374
- package/scripts/gds/move-escalation.js +5 -140
- package/scripts/gds/newcomer-floor.js +6 -420
- package/scripts/gds/newcomer-floor.test.js +6 -234
- package/scripts/gds/next-number.js +6 -162
- package/scripts/gds/oauth-secret.js +5 -200
- package/scripts/gds/onboard.js +5 -265
- package/scripts/gds/onboarding-analyze.js +6 -225
- package/scripts/gds/onboarding-config.js +6 -179
- package/scripts/gds/onboarding-ship.js +6 -91
- package/scripts/gds/pack-env-prefix.js +5 -72
- package/scripts/gds/package-core.js +5 -1102
- package/scripts/gds/page-inventory.js +5 -346
- package/scripts/gds/page-reader.js +5 -720
- package/scripts/gds/paste-token.js +6 -211
- package/scripts/gds/plain-cards.js +5 -350
- package/scripts/gds/portability-smoke-art.sh +7 -84
- package/scripts/gds/portability-smoke-memory.sh +7 -175
- package/scripts/gds/preflight.js +5 -212
- package/scripts/gds/probe-cache.js +5 -244
- package/scripts/gds/prove-strict-versioning.js +6 -283
- package/scripts/gds/provision-auto-upgrade.js +5 -161
- package/scripts/gds/provision-byo-host.js +5 -67
- package/scripts/gds/provision-capacity.js +5 -78
- package/scripts/gds/provision-caps.js +5 -62
- package/scripts/gds/provision-config.js +5 -232
- package/scripts/gds/provision-core-upgrade.js +5 -1165
- package/scripts/gds/provision-disconnect.js +5 -87
- package/scripts/gds/provision-github-setup.js +5 -167
- package/scripts/gds/provision-net.js +5 -356
- package/scripts/gds/provision-pin-key.js +5 -175
- package/scripts/gds/provision-pin-replay.js +5 -125
- package/scripts/gds/provision-process.js +5 -169
- package/scripts/gds/provision-render.js +5 -200
- package/scripts/gds/provision-repo-auth.js +5 -163
- package/scripts/gds/provision-repo-private.js +5 -97
- package/scripts/gds/provision-repo.js +5 -1336
- package/scripts/gds/provision-teardown.js +5 -105
- package/scripts/gds/provision-units.js +5 -468
- package/scripts/gds/provision.js +5 -1477
- package/scripts/gds/publish-credential-check.js +6 -65
- package/scripts/gds/publish-integration-gate.js +5 -140
- package/scripts/gds/publish-manifest.js +5 -437
- package/scripts/gds/publish-watch.js +5 -266
- package/scripts/gds/pulse.js +6 -335
- package/scripts/gds/push-main.js +5 -54
- package/scripts/gds/push-path-brief.js +5 -98
- package/scripts/gds/read-session-export.js +5 -357
- package/scripts/gds/reauth.js +6 -154
- package/scripts/gds/recall.js +6 -182
- package/scripts/gds/redteam-patrol.js +5 -435
- package/scripts/gds/regen-instance-docs.js +5 -45
- package/scripts/gds/release-core.js +5 -78
- package/scripts/gds/release-notes.js +5 -270
- package/scripts/gds/release.js +6 -138
- package/scripts/gds/rename-history-check.js +5 -367
- package/scripts/gds/rename-ledger-prose.js +5 -480
- package/scripts/gds/render-api.js +5 -196
- package/scripts/gds/render-check.js +5 -204
- package/scripts/gds/render-ideas.js +6 -225
- package/scripts/gds/render-payload.js +5 -84
- package/scripts/gds/repo-metrics.js +6 -362
- package/scripts/gds/review-sheet.js +5 -106
- package/scripts/gds/role-pack-guard.js +5 -141
- package/scripts/gds/route-shadow-guard.js +5 -173
- package/scripts/gds/routine-schedule.js +5 -281
- package/scripts/gds/run-routine.js +5 -255
- package/scripts/gds/run-unit-tests.js +6 -659
- package/scripts/gds/runner-drift.js +5 -149
- package/scripts/gds/sandbox-stage.js +6 -458
- package/scripts/gds/scope-map-guard.js +5 -299
- package/scripts/gds/scope-roster-guard.js +5 -117
- package/scripts/gds/seam-wiring-guard.js +5 -274
- package/scripts/gds/search-ingest-db.js +6 -287
- package/scripts/gds/search-ingest-md.js +6 -268
- package/scripts/gds/seed-bongos-v1-idea-routing-tasks.js +6 -152
- package/scripts/gds/seed-bv1-profiles-tasks.js +6 -135
- package/scripts/gds/seed-bv2-ideator-surface-tasks.js +6 -390
- package/scripts/gds/seed-staging.sh +7 -116
- package/scripts/gds/seed-verify-criteria.js +6 -124
- package/scripts/gds/sequence.js +6 -596
- package/scripts/gds/session-cost.js +6 -429
- package/scripts/gds/session-digest-build.js +6 -293
- package/scripts/gds/session-digest.js +6 -199
- package/scripts/gds/session-eval.js +6 -630
- package/scripts/gds/session-transcript-build.js +6 -155
- package/scripts/gds/session-transcript-upload.js +6 -29
- package/scripts/gds/session.js +6 -403
- package/scripts/gds/setup.js +6 -645
- package/scripts/gds/ship-check.js +5 -85
- package/scripts/gds/ship-deploy-target.js +5 -392
- package/scripts/gds/ship-escalation.js +5 -166
- package/scripts/gds/ship-finish.js +5 -419
- package/scripts/gds/ship-flow.js +5 -1216
- package/scripts/gds/ship-git.js +5 -99
- package/scripts/gds/ship-grade-steps.js +5 -546
- package/scripts/gds/ship-grade.js +5 -425
- package/scripts/gds/ship-honesty.js +5 -312
- package/scripts/gds/ship-io.js +5 -138
- package/scripts/gds/ship-land.js +5 -1129
- package/scripts/gds/ship-memory-sync.js +5 -248
- package/scripts/gds/ship-merge-gate.js +5 -224
- package/scripts/gds/ship-merge.js +5 -465
- package/scripts/gds/ship-mode-ask.js +5 -137
- package/scripts/gds/ship-mode-manual.js +5 -53
- package/scripts/gds/ship-preflight-steps.js +5 -398
- package/scripts/gds/ship-regen.js +5 -313
- package/scripts/gds/ship-resume.js +5 -200
- package/scripts/gds/ship-session-upload.js +5 -312
- package/scripts/gds/ship-state.js +5 -109
- package/scripts/gds/ship-surprise.js +5 -83
- package/scripts/gds/ship-visual.js +5 -74
- package/scripts/gds/ship.js +5 -380
- package/scripts/gds/shipping-mode.js +5 -69
- package/scripts/gds/skill-lint.js +5 -248
- package/scripts/gds/skill-preflight.js +5 -359
- package/scripts/gds/smoke-batch-claim.sh +7 -237
- package/scripts/gds/smoke-batch-release.sh +7 -315
- package/scripts/gds/smoke-claim-consistency.sh +7 -221
- package/scripts/gds/smoke-dependencies.sh +7 -142
- package/scripts/gds/smoke-gds.js +6 -255
- package/scripts/gds/smoke-write.sh +7 -274
- package/scripts/gds/source-text-test-scan.js +7 -0
- package/scripts/gds/spark.js +6 -293
- package/scripts/gds/stale-worktrees.js +5 -210
- package/scripts/gds/start-goals.js +5 -101
- package/scripts/gds/start.js +6 -1089
- package/scripts/gds/status.js +6 -544
- package/scripts/gds/strand-watch.js +5 -313
- package/scripts/gds/stranded-rows.js +5 -198
- package/scripts/gds/stray-unit-sweep.sh +7 -70
- package/scripts/gds/surface.js +5 -100
- package/scripts/gds/task.js +6 -272
- package/scripts/gds/test-path-guard.js +5 -97
- package/scripts/gds/triage.js +6 -741
- package/scripts/gds/turn-end-sound.js +5 -72
- package/scripts/gds/tweak-halt.js +5 -68
- package/scripts/gds/tweak-renders.js +5 -198
- package/scripts/gds/uat.js +6 -119
- package/scripts/gds/ui-kit-transform.js +5 -41
- package/scripts/gds/update-channel.js +5 -510
- package/scripts/gds/update-sweep.js +5 -827
- package/scripts/gds/upgrade-artist-gate.js +5 -45
- package/scripts/gds/upgrade-commit-identity.js +5 -31
- package/scripts/gds/upgrade-migrate.js +5 -223
- package/scripts/gds/upgrade-operator.js +6 -73
- package/scripts/gds/upgrade-outcome.js +5 -173
- package/scripts/gds/upgrade.js +5 -1497
- package/scripts/gds/validate-design.js +5 -10
- package/scripts/gds/version-close.js +6 -620
- package/scripts/gds/version-literal-guard.js +5 -138
- package/scripts/gds/version-select.js +5 -77
- package/scripts/gds/visual-review-nudge.js +5 -38
- package/scripts/gds/wedge-remedy.js +5 -173
- package/scripts/gds/worktree-claim-guard.js +5 -129
- package/scripts/gds/worktree.js +6 -448
- package/scripts/hall-preview/refresh-fixtures.js +1 -1
- package/scripts/hall-preview/server.js +2 -2
- package/scripts/migrate.sh +3 -3
- package/scripts/public-mirror-export.js +3 -3
- package/scripts/security/dep-audit.js +50 -124
- package/scripts/setup-builder.js +7 -7
- package/src/bongos/api-errors.js +1 -0
- package/src/bongos/api-prefix.js +1 -1
- package/src/bongos/auth-github.js +19 -3
- package/src/bongos/auth-idp.js +7 -0
- package/src/bongos/claim-attribution.js +2 -2
- package/src/bongos/core-moves.js +1 -1
- package/src/bongos/core-update.js +3 -3
- package/src/bongos/craft-mode.js +2 -2
- package/src/bongos/db-kernel.js +15 -3
- package/src/bongos/db.js +30 -4
- package/src/bongos/github-repos.js +1 -1
- package/src/bongos/llm-cache.js +1 -1
- package/src/bongos/llm-pricing.js +1 -1
- package/src/bongos/metrics.js +1 -1
- package/src/bongos/middleware/rate-limit.js +2 -2
- package/src/bongos/module-listing.js +93 -1
- package/src/bongos/module-scope-map.js +90 -85
- package/src/bongos/module-store.js +1 -1
- package/src/bongos/module-submissions.js +1 -1
- package/src/bongos/optimizer.js +1 -1
- package/src/bongos/package-registry.js +1 -1
- package/src/bongos/path-match.js +1 -1
- package/src/bongos/permission-path-check.js +3 -3
- package/src/bongos/platform-visibility-gate.js +3 -5
- package/src/bongos/prelaunch-gate.js +7 -6
- package/src/bongos/route-rank-check.js +2 -2
- package/src/bongos/routes/auth.js +15 -2
- package/src/bongos/routes/backup.js +1 -1
- package/src/bongos/routes/builders.js +29 -1
- package/src/bongos/routes/me.js +49 -18
- package/src/bongos/routes/modules.js +29 -9
- package/src/bongos/routes/public.js +3 -72
- package/src/bongos/schema-lag.js +1 -1
- package/src/bongos/sensitive-surfaces.js +1 -1
- package/src/bongos/serve-internal.js +65 -16
- package/src/bongos/software-update.js +2 -2
- package/src/bongos/upgrade-hold.js +3 -3
- package/src/hall-look.js +6 -5
- package/src/module-api.js +3 -3
- package/src/module-loader/catalog.js +1 -1
- package/src/module-loader/error-tally.js +3 -3
- package/src/module-loader/manifest-schema.js +3 -3
- package/src/platform-server.js +10 -0
- package/src/role-responsibilities.js +1 -1
- package/src/stale-timer.js +2 -2
- package/tests/accessibility_replay.mjs +1 -1
- package/tests/activity_rollup_order_db.mjs +1 -1
- package/tests/activity_snapshots_db.mjs +1 -1
- package/tests/adopt_detect.mjs +1 -1
- package/tests/adopt_import.mjs +1 -1
- package/tests/adopt_preflight.mjs +1 -1
- package/tests/adr_0089_scope.mjs +10 -7
- package/tests/adr_0162_citation.mjs +1 -1
- package/tests/adr_0162_gate_citation.mjs +1 -1
- package/tests/agent_invoke.mjs +1 -1
- package/tests/agent_invoke_live.mjs +3 -3
- package/tests/agents_cron_trigger.mjs +2 -2
- package/tests/agents_roster.mjs +1 -1
- package/tests/agents_sync.mjs +4 -4
- package/tests/allow_rule_guard.mjs +20 -20
- package/tests/api_alias_caller_ratchet.mjs +9 -10
- package/tests/api_alias_exceptions.mjs +7 -6
- package/tests/api_artifacts.mjs +214 -0
- package/tests/api_cli_flags.mjs +3 -3
- package/tests/api_client.mjs +56 -54
- package/tests/api_docs.mjs +30 -9
- package/tests/api_error_envelope_buildcheck.mjs +1 -1
- package/tests/api_msys_path_repair.mjs +2 -2
- package/tests/architect.mjs +1 -1
- package/tests/art_stage.mjs +2 -2
- package/tests/artifact_audit.mjs +2 -2
- package/tests/atlas.mjs +1 -1
- package/tests/audit_deps.mjs +1 -1
- package/tests/audit_gate.mjs +1 -1
- package/tests/auth_flow_slice1.mjs +3 -3
- package/tests/auth_inactive_builder.mjs +43 -5
- package/tests/auth_session_expiry_db.mjs +16 -4
- package/tests/auth_session_ttl.mjs +23 -0
- package/tests/authorship_audit.mjs +2 -2
- package/tests/autobongos_cadence.mjs +1 -1
- package/tests/autobongos_fence.mjs +1 -1
- package/tests/autobongos_grade_cap.mjs +2 -2
- package/tests/autobongos_heartbeat_head.mjs +1 -1
- package/tests/autobongos_host_access.mjs +3 -3
- package/tests/autobongos_loop.mjs +17 -17
- package/tests/autobongos_service_ps1.mjs +3 -3
- package/tests/autobongos_tweak_lane.mjs +2 -2
- package/tests/autobongos_verify.mjs +2 -2
- package/tests/autonomous_fit_protected_paths.mjs +3 -3
- package/tests/autonomy_config_idle.mjs +1 -1
- package/tests/autonomy_daily_checks.mjs +201 -0
- package/tests/autonomy_digest.mjs +1 -1
- package/tests/autonomy_gate.mjs +1 -1
- package/tests/autonomy_gauge.mjs +2 -2
- package/tests/autonomy_runner_identity.mjs +1 -1
- package/tests/backfill_sessions.mjs +8 -8
- package/tests/backfill_subagent_rewards.mjs +1 -1
- package/tests/backfill_task_rewards.mjs +2 -2
- package/tests/backlog_review.mjs +3 -3
- package/tests/baseline_staleness.mjs +2 -2
- package/tests/bfg.mjs +11 -5
- package/tests/bfg_write.mjs +20 -11
- package/tests/blockers_hall.mjs +14 -4
- package/tests/blockers_page_ui.mjs +56 -12
- package/tests/bongos_dispatch.mjs +5 -5
- package/tests/bongos_login.mjs +2 -2
- package/tests/bug_attachment_audit.mjs +1 -1
- package/tests/bug_attachment_recover.mjs +2 -2
- package/tests/bug_triage.mjs +3 -3
- package/tests/build_info.mjs +1 -1
- package/tests/builder_tester_tag.mjs +184 -0
- package/tests/bump_version.mjs +3 -3
- package/tests/canonical_profile_url.mjs +1 -1
- package/tests/capture_error_format.mjs +1 -1
- package/tests/capture_goal_routing.mjs +2 -2
- package/tests/category_advisory_guard.mjs +3 -3
- package/tests/claim_error_surface.mjs +2 -2
- package/tests/claim_from_task_and_home.mjs +1 -1
- package/tests/claim_gate_open_blocker.mjs +7 -4
- package/tests/claim_gate_rebase.mjs +12 -8
- package/tests/claim_recall.mjs +4 -4
- package/tests/claim_resolve_worktree_lock.mjs +1 -1
- package/tests/claude_materialize.mjs +68 -68
- package/tests/clawback_confirmed_backlog.mjs +8 -5
- package/tests/cli_allowlist_permissions.mjs +11 -11
- package/tests/cli_dispatcher.mjs +2 -2
- package/tests/cli_err_code.mjs +6 -6
- package/tests/cli_exit_no_abort.mjs +7 -7
- package/tests/cli_lib_formatters.mjs +2 -2
- package/tests/cli_sessions.mjs +5 -5
- package/tests/cli_surface.mjs +15 -15
- package/tests/cli_token_reissue.mjs +2 -2
- package/tests/client_baseurl_guard.mjs +1 -1
- package/tests/client_bundle_route.mjs +35 -4
- package/tests/cloud_bongos_pack.mjs +1 -1
- package/tests/community_leaderboard_db.mjs +1 -1
- package/tests/conductor.mjs +18 -18
- package/tests/conflict_resolve.mjs +14 -16
- package/tests/consumer_layout_boot.mjs +12 -12
- package/tests/context_pack.mjs +6 -6
- package/tests/control_manifest.mjs +4 -4
- package/tests/copy_desk_page_reads.mjs +1 -1
- package/tests/copy_desk_page_release.mjs +192 -0
- package/tests/copy_inventory.mjs +2 -2
- package/tests/core_auto_upgrade.mjs +1 -1
- package/tests/core_move_notice.mjs +2 -2
- package/tests/core_origin_follow.mjs +7 -7
- package/tests/core_pin_sync.mjs +3 -3
- package/tests/core_upgrade_door.mjs +2 -2
- package/tests/core_upgrade_owner_door.mjs +34 -1
- package/tests/core_upgrade_runner.mjs +19 -19
- package/tests/credential_presence.mjs +2 -2
- package/tests/credit_grant.mjs +3 -3
- package/tests/credit_log_single_writer.mjs +5 -5
- package/tests/criterion_ref_status.mjs +2 -2
- package/tests/cross_discipline_priority_direction.mjs +3 -3
- package/tests/cutover_codemod.mjs +2 -4
- package/tests/db_backup_nightly.mjs +1 -1
- package/tests/db_backup_offsite.mjs +1 -1
- package/tests/db_ownership_handover.mjs +2 -2
- package/tests/dead_deps.mjs +3 -3
- package/tests/dependency_advisory.mjs +1 -1
- package/tests/deploy_audit_gate.mjs +4 -4
- package/tests/deploy_divergence_line.mjs +36 -16
- package/tests/deploy_page_projects.mjs +35 -4
- package/tests/dev_lib.mjs +2 -2
- package/tests/dev_windows.mjs +2 -2
- package/tests/diagram_facts_offset.mjs +1 -1
- package/tests/diagram_repo_slug.mjs +1 -1
- package/tests/diff_derived_signals.mjs +2 -2
- package/tests/dns_preflight.mjs +2 -2
- package/tests/do_api.mjs +3 -3
- package/tests/doc_cli_guard.mjs +28 -28
- package/tests/doc_comment_coverage.mjs +1 -1
- package/tests/doc_control_claims.mjs +11 -11
- package/tests/docs_entropy.mjs +2 -2
- package/tests/docs_openapi_route.mjs +8 -6
- package/tests/doctor_hooks.mjs +1 -1
- package/tests/edit_hints.mjs +3 -2
- package/tests/effective_visibility_predicate.mjs +1 -19
- package/tests/env_knobs_neutral_prefix.mjs +13 -13
- package/tests/exec_path_guard.mjs +4 -4
- package/tests/executed_closure.mjs +18 -12
- package/tests/file_map.mjs +1 -1
- package/tests/find_untested.mjs +13 -13
- package/tests/first_admin_bootstrap.mjs +1 -1
- package/tests/fitness.mjs +16 -16
- package/tests/fitness_gds_ratchet.mjs +2 -2
- package/tests/fitness_installed_core.mjs +3 -3
- package/tests/fitness_no_raw_nul.mjs +1 -1
- package/tests/fitness_ratchets.mjs +3 -3
- package/tests/fitness_scope_roster.mjs +2 -2
- package/tests/fitness_two_root.mjs +8 -8
- package/tests/fixtures/accessibility-replay.json +5 -5
- package/tests/fixtures/grade-replay/recorded-panel-grades.json +1 -1
- package/tests/fixtures/ideator-prefold/README.md +1 -1
- package/tests/fixtures/page-ledger.mjs +22 -0
- package/tests/fixtures/session-506-digest.json +5 -5
- package/tests/gate_approvals.mjs +50 -0
- package/tests/gate_review.mjs +8 -8
- package/tests/gating_review_retired.mjs +2 -2
- package/tests/gen_freshness.mjs +3 -3
- package/tests/git_guard.mjs +3 -3
- package/tests/git_merge_regen.mjs +41 -65
- package/tests/github_one_trip.mjs +4 -4
- package/tests/github_pick_up.mjs +2 -2
- package/tests/github_push_merge_driver.mjs +1 -1
- package/tests/go_live.mjs +3 -2
- package/tests/goal_category.mjs +1 -1
- package/tests/goal_cli.mjs +2 -2
- package/tests/goal_create_spec_entry.mjs +1 -1
- package/tests/goal_invite_consent.mjs +3 -1
- package/tests/goal_move.mjs +1 -1
- package/tests/goal_working_area.mjs +1 -1
- package/tests/government_agent_asks.mjs +7 -7
- package/tests/government_board_room_copy.mjs +6 -1
- package/tests/government_board_view.mjs +39 -0
- package/tests/government_board_vote_ui.mjs +39 -1
- package/tests/government_config.mjs +2 -2
- package/tests/government_live_proof_shape.mjs +1 -1
- package/tests/government_protected_surfaces.mjs +54 -53
- package/tests/government_require_permission.mjs +9 -1
- package/tests/government_vanilla_boot.mjs +1 -1
- package/tests/government_vocabulary.mjs +2 -2
- package/tests/government_walk.mjs +2 -2
- package/tests/grade_body_limit.mjs +6 -4
- package/tests/grade_correlation_audit.mjs +3 -3
- package/tests/grade_diff_hash.mjs +1 -1
- package/tests/grade_engine_replay.mjs +2 -2
- package/tests/grade_server_authoritative.mjs +1 -1
- package/tests/grade_unavailable_display.mjs +1 -1
- package/tests/grader.mjs +8 -24
- package/tests/grader_generated_provenance.mjs +14 -14
- package/tests/grader_no_artifact.mjs +1 -1
- package/tests/grader_prompt_fencing.mjs +1 -1
- package/tests/grader_quality_window_overflow.mjs +1 -1
- package/tests/grader_reader_lens.mjs +3 -3
- package/tests/grader_regrade_delta.mjs +1 -1
- package/tests/grader_unbacked_score.mjs +2 -2
- package/tests/hall_acclaim_vote_control.mjs +113 -0
- package/tests/hall_asset_cache.mjs +127 -0
- package/tests/hall_audit.mjs +63 -0
- package/tests/hall_board_world.mjs +20 -0
- package/tests/hall_city_card_words.mjs +61 -0
- package/tests/hall_client_request_shape.mjs +5 -1
- package/tests/hall_home_ships_bounded.mjs +160 -0
- package/tests/hall_landing_boot.mjs +15 -2
- package/tests/hall_nav.mjs +33 -0
- package/tests/hall_onboarding_bongos_setup.mjs +1 -1
- package/tests/hall_oversight_world.mjs +44 -4
- package/tests/hall_palette.mjs +12 -9
- package/tests/hall_preview_security.mjs +1 -1
- package/tests/hall_profile_world.mjs +17 -0
- package/tests/hall_reading_world.mjs +16 -1
- package/tests/hall_roster_world.mjs +2 -1
- package/tests/hall_studio_world.mjs +4 -1
- package/tests/hall_work_history_id.mjs +39 -0
- package/tests/held_tweak_reporting.mjs +4 -4
- package/tests/helpers.mjs +3 -3
- package/tests/home_bounded_reads.mjs +1 -1
- package/tests/home_isolation_guard.mjs +1 -1
- package/tests/hook_core_resolve.mjs +7 -7
- package/tests/hook_user_agents.mjs +1 -1
- package/tests/hooks_drain.mjs +2 -2
- package/tests/host_topology_skips.mjs +1 -1
- package/tests/howto_guide.mjs +1 -1
- package/tests/howto_moments.mjs +3 -3
- package/tests/hub_account_page.mjs +1 -1
- package/tests/idea_capture_grades.mjs +2 -2
- package/tests/idea_develop_spark.mjs +1 -1
- package/tests/idea_filed_via.mjs +2 -2
- package/tests/idea_ideate_full.mjs +1 -1
- package/tests/idea_spark_mark.mjs +1 -1
- package/tests/idea_spark_queue.mjs +1 -1
- package/tests/idea_triage.mjs +1 -1
- package/tests/idea_triage_grade.mjs +3 -3
- package/tests/idea_vote_permission.mjs +113 -0
- package/tests/idea_votes_fold_db.mjs +123 -0
- package/tests/infra_exec_paths.mjs +12 -12
- package/tests/init.mjs +2 -2
- package/tests/instance_db_migrated_on_code_move.mjs +5 -5
- package/tests/instance_feedback.mjs +9 -9
- package/tests/instance_mismatch_guard.mjs +2 -2
- package/tests/integration_parked_ratchet.mjs +24 -2
- package/tests/intent_retry.mjs +1 -1
- package/tests/interaction_posture.mjs +3 -3
- package/tests/invite_expiry_db.mjs +1 -1
- package/tests/joinability_invite_only.mjs +1 -1
- package/tests/karma_vote_lists.mjs +270 -0
- package/tests/key-card.mjs +2 -2
- package/tests/key-status.mjs +2 -2
- package/tests/knip_ratchet_ambient.mjs +2 -2
- package/tests/known_failing_ratchet.mjs +1 -1
- package/tests/land_watch.mjs +2 -2
- package/tests/landing_legal_pages.mjs +1 -1
- package/tests/landing_page.mjs +2 -2
- package/tests/leaderboard_roles.mjs +4 -1
- package/tests/leak_scan_allowlist.mjs +8 -8
- package/tests/leak_scan_fail_closed.mjs +1 -1
- package/tests/lib_sh_resolution.mjs +9 -9
- package/tests/lifecycle-card.mjs +7 -7
- package/tests/linkify_check.mjs +2 -2
- package/tests/linkify_refs.mjs +1 -1
- package/tests/llm-cache-route.mjs +1 -1
- package/tests/local_preview.mjs +2 -2
- package/tests/main_audit.mjs +3 -3
- package/tests/main_audit_attestation.mjs +1 -1
- package/tests/main_audit_db_roster.mjs +2 -2
- package/tests/main_worktree_busy_reason.mjs +3 -3
- package/tests/markdown_line_endings.mjs +2 -2
- package/tests/me_streak_leaderboard_queries.mjs +193 -0
- package/tests/membership_kind_lockstep.mjs +1 -1
- package/tests/memory_isolation.mjs +16 -8
- package/tests/memory_map.mjs +2 -2
- package/tests/memory_pull.mjs +33 -25
- package/tests/merge_driver_register.mjs +3 -3
- package/tests/migration_allocation.mjs +2 -2
- package/tests/migration_namespace.mjs +1 -1
- package/tests/migrations_forward_safe.mjs +1 -1
- package/tests/mingle.mjs +1 -1
- package/tests/mirror_lineage_fulltree.mjs +3 -3
- package/tests/mirror_lineage_proof.mjs +2 -2
- package/tests/mirror_redact.mjs +4 -4
- package/tests/missing_dep_classify.mjs +3 -3
- package/tests/module-scope-map.mjs +22 -22
- package/tests/module_api_lazy.mjs +1 -1
- package/tests/module_assess_docs.mjs +2 -2
- package/tests/module_assess_installs.mjs +3 -3
- package/tests/module_assess_price_parity.mjs +5 -5
- package/tests/module_assess_score.mjs +5 -5
- package/tests/module_assess_security.mjs +4 -4
- package/tests/module_assess_tests.mjs +3 -3
- package/tests/module_assessments_migration.mjs +1 -1
- package/tests/module_catalog.mjs +2 -2
- package/tests/module_cli.mjs +3 -3
- package/tests/module_entitlements.mjs +1 -1
- package/tests/module_error_counts.mjs +1 -1
- package/tests/module_install.mjs +4 -4
- package/tests/module_loader.mjs +3 -1
- package/tests/module_owned_tests.mjs +1 -1
- package/tests/module_release_channels.mjs +1 -1
- package/tests/module_store_howto.mjs +3 -3
- package/tests/module_store_listing.mjs +139 -2
- package/tests/module_store_publish.mjs +4 -4
- package/tests/module_store_publish_route.mjs +1 -1
- package/tests/module_store_reassess.mjs +1 -1
- package/tests/module_store_registry_migration.mjs +1 -1
- package/tests/module_test_runner.mjs +3 -3
- package/tests/module_update.mjs +4 -4
- package/tests/module_upgrade_updates.mjs +1 -1
- package/tests/move_escalation.mjs +2 -2
- package/tests/nav_permission_atoms.mjs +3 -2
- package/tests/needs_rebase.mjs +7 -3
- package/tests/newcomer_floor.mjs +1 -1
- package/tests/next_number.mjs +1 -1
- package/tests/no_artifact_escalation.mjs +3 -3
- package/tests/npm_release_where.mjs +1 -1
- package/tests/oauth_secret.mjs +2 -2
- package/tests/onboard.mjs +6 -6
- package/tests/onboarding_gate.mjs +2 -2
- package/tests/opt_in_skill_modules.mjs +3 -3
- package/tests/own_scope_guard.mjs +1 -1
- package/tests/own_session_revoke.mjs +4 -1
- package/tests/package_core.mjs +10 -11
- package/tests/page_inventory.mjs +5 -5
- package/tests/page_reader.mjs +7 -7
- package/tests/page_tweak_hold.mjs +6 -6
- package/tests/parallel-load.mjs +1 -1
- package/tests/paste_token_api_base.mjs +1 -1
- package/tests/paste_token_session_store.mjs +2 -2
- package/tests/pending_invite_purge_db.mjs +1 -1
- package/tests/permission_path.mjs +1 -1
- package/tests/pin_replay.mjs +1 -1
- package/tests/pin_write_key.mjs +7 -7
- package/tests/plain_cards.mjs +15 -15
- package/tests/pr_assign.mjs +1 -1
- package/tests/pre_push_hook.mjs +3 -3
- package/tests/preflight_checks.mjs +2 -2
- package/tests/prelaunch_gate.mjs +1 -1
- package/tests/privacy_matrix.mjs +1 -1
- package/tests/probe_cache.mjs +6 -6
- package/tests/profile_connections_ui.mjs +4 -3
- package/tests/profile_fields.mjs +11 -1
- package/tests/profile_privacy_owner_view.mjs +1 -1
- package/tests/profile_role_headline.mjs +10 -9
- package/tests/project_admin_console_model.mjs +1 -1
- package/tests/projects_hub.mjs +1 -1
- package/tests/projects_hub_cloud_hop.mjs +1 -1
- package/tests/promote_goal_id.mjs +6 -6
- package/tests/promotion_sweep.mjs +1 -1
- package/tests/provision.mjs +24 -24
- package/tests/provision_account_identity.mjs +2 -2
- package/tests/provision_byo_host.mjs +1 -1
- package/tests/provision_caddy_wiring.mjs +2 -2
- package/tests/provision_disconnect.mjs +2 -2
- package/tests/provision_dns_first.mjs +1 -1
- package/tests/provision_render.mjs +9 -9
- package/tests/provision_repo_private.mjs +3 -3
- package/tests/provision_resource_caps.mjs +5 -5
- package/tests/provision_restart.mjs +3 -3
- package/tests/provision_settings_apply.mjs +7 -7
- package/tests/provision_teardown_address.mjs +2 -2
- package/tests/provisioning_capacity.mjs +5 -5
- package/tests/provisioning_credential_preflight.mjs +1 -1
- package/tests/provisioning_disconnect.mjs +1 -1
- package/tests/provisioning_error_note_scope.mjs +4 -4
- package/tests/provisioning_paid_shape_gate.mjs +2 -2
- package/tests/provisioning_planet_physics.mjs +16 -0
- package/tests/provisioning_runner_drift_notice.mjs +2 -2
- package/tests/provisioning_settings_env.mjs +1 -1
- package/tests/pruned_lockfile_integrity.mjs +1 -1
- package/tests/public_mirror_export.mjs +1 -1
- package/tests/publish_integration_gate.mjs +2 -2
- package/tests/publish_manifest.mjs +6 -6
- package/tests/publish_watch.mjs +1 -1
- package/tests/push_path_brief.mjs +2 -2
- package/tests/raise.mjs +248 -0
- package/tests/rank_roles_audit.mjs +1 -1
- package/tests/rank_tier_single_source.mjs +2 -2
- package/tests/rate_limit_public.mjs +1 -1
- package/tests/read_default_meter.mjs +2 -2
- package/tests/read_session_export.mjs +1 -1
- package/tests/rebase_gate_set_aside.mjs +1 -1
- package/tests/recall_cli.mjs +1 -1
- package/tests/recall_corpus_health.mjs +3 -2
- package/tests/recall_hints.mjs +1 -1
- package/tests/recruiter_sliver_boundary.mjs +1 -1
- package/tests/redteam_patrol.mjs +2 -2
- package/tests/regrade_actual_minutes.mjs +2 -2
- package/tests/regrade_eligibility.mjs +2 -2
- package/tests/release_core.mjs +2 -2
- package/tests/release_notes.mjs +4 -4
- package/tests/rename_history_restraint.mjs +3 -3
- package/tests/rename_ledger_prose.mjs +6 -6
- package/tests/render_api.mjs +1 -1
- package/tests/render_check.mjs +4 -4
- package/tests/render_deploy.mjs +1 -1
- package/tests/repo_info_binding.mjs +1 -1
- package/tests/repo_map.mjs +5 -5
- package/tests/reward_mode_cost_plus_only.mjs +7 -3
- package/tests/reward_mode_surfacing.mjs +1 -1
- package/tests/role_responsibilities.mjs +1 -1
- package/tests/route_permission_check.mjs +1 -1
- package/tests/route_shadow_guard.mjs +1 -1
- package/tests/route_validation.mjs +1 -1
- package/tests/routine_capture_kind.mjs +24 -13
- package/tests/routine_schedule.mjs +51 -9
- package/tests/run_routine.mjs +5 -5
- package/tests/run_routine_two_root.mjs +5 -5
- package/tests/runner_drift.mjs +17 -17
- package/tests/sandbox_stage.mjs +5 -5
- package/tests/scope_map_guard.mjs +7 -7
- package/tests/scouting_owner_access_and_reach.mjs +1 -1
- package/tests/scripts_gds_forwarders.mjs +224 -0
- package/tests/scrubber_corpus.mjs +2 -2
- package/tests/seam_wiring_guard.mjs +1 -1
- package/tests/search_ingest.mjs +2 -2
- package/tests/search_ingest_db.mjs +1 -1
- package/tests/search_ingest_nul.mjs +6 -6
- package/tests/seed_verify_criteria.mjs +3 -3
- package/tests/sequence.mjs +3 -3
- package/tests/served_paths_shipped.mjs +3 -3
- package/tests/session_506_regression.mjs +1 -1
- package/tests/session_accessibility.mjs +1 -1
- package/tests/session_caps.mjs +1 -1
- package/tests/session_cost.mjs +1 -1
- package/tests/session_digest.mjs +2 -2
- package/tests/session_eval.mjs +6 -6
- package/tests/session_index.mjs +1 -1
- package/tests/session_records.mjs +4 -4
- package/tests/session_rename_fallback.mjs +2 -2
- package/tests/session_reward_on_land.mjs +7 -149
- package/tests/session_reward_on_land_db.mjs +191 -0
- package/tests/session_reward_reconcile.mjs +6 -88
- package/tests/session_reward_reconcile_db.mjs +132 -0
- package/tests/session_transcript.mjs +1 -1
- package/tests/sessions_kit_pager.mjs +2 -1
- package/tests/setup_device_flow_fallback.mjs +2 -2
- package/tests/setup_smoke.mjs +12 -5
- package/tests/setup_status_facts.mjs +54 -12
- package/tests/ship_autolinkify.mjs +2 -2
- package/tests/ship_automerge_injection.mjs +1 -1
- package/tests/ship_base_flag.mjs +1 -1
- package/tests/ship_broadcast_routing.mjs +1 -1
- package/tests/ship_broadcast_server.mjs +2 -2
- package/tests/ship_builder_model.mjs +1 -1
- package/tests/ship_cannot_lie.mjs +9 -9
- package/tests/ship_card.mjs +2 -2
- package/tests/ship_ci_deploy.mjs +7 -7
- package/tests/ship_error_shape.mjs +1 -1
- package/tests/ship_land_ci_not_started.mjs +3 -3
- package/tests/ship_land_conflict.mjs +3 -3
- package/tests/ship_land_proof.mjs +3 -3
- package/tests/ship_land_red_pr.mjs +5 -5
- package/tests/ship_merge_gate.mjs +14 -14
- package/tests/ship_mode.mjs +1 -1
- package/tests/ship_mode_first_ship.mjs +4 -4
- package/tests/ship_mode_hands_off.mjs +8 -8
- package/tests/ship_post_land_verify.mjs +1 -1
- package/tests/ship_preflight.mjs +19 -19
- package/tests/ship_premerge.mjs +1 -1
- package/tests/ship_publish_error.mjs +2 -2
- package/tests/ship_push_diagnosis.mjs +1 -1
- package/tests/ship_regen_copy_inventory.mjs +3 -3
- package/tests/ship_resume.mjs +4 -4
- package/tests/ship_smoke_gate.mjs +1 -1
- package/tests/ship_upload_skip.mjs +1 -1
- package/tests/ship_upstream_deletion.mjs +1 -1
- package/tests/ship_vendored_instance.mjs +8 -8
- package/tests/ship_visual_regrade.mjs +3 -3
- package/tests/ship_zero_commit.mjs +1 -1
- package/tests/skill_docs_unavailable_regrade.mjs +3 -3
- package/tests/skill_friction_kind.mjs +1 -1
- package/tests/skill_grade_recover.mjs +1 -1
- package/tests/skill_grader_health.mjs +1 -1
- package/tests/skill_lint.mjs +1 -1
- package/tests/skill_menu_ruling.mjs +1 -1
- package/tests/skill_preflight.mjs +7 -7
- package/tests/skip_is_not_pass.mjs +22 -1
- package/tests/smoke_dependencies_witness.mjs +2 -2
- package/tests/smoke_preflight.mjs +1 -1
- package/tests/smoke_target.mjs +2 -2
- package/tests/smoke_write_contract.mjs +2 -2
- package/tests/sound_player.mjs +8 -8
- package/tests/source_text_test_ratchet.mjs +97 -0
- package/tests/speciality_corpus_scope.mjs +1 -1
- package/tests/speciality_session_skills.mjs +1 -1
- package/tests/sso_checkin_legacy_field_gone.mjs +4 -2
- package/tests/stale_timer.mjs +3 -3
- package/tests/stale_worktrees.mjs +1 -1
- package/tests/start_env_guard.mjs +1 -1
- package/tests/start_goal_first.mjs +3 -3
- package/tests/start_inbox_count.mjs +1 -1
- package/tests/start_rebase_warning.mjs +1 -1
- package/tests/status_default_version.mjs +3 -3
- package/tests/status_mirror_sync.mjs +1 -1
- package/tests/status_page_no_dead_uptime.mjs +80 -0
- package/tests/stop_refcheck.mjs +1 -1
- package/tests/strand_watch.mjs +1 -1
- package/tests/stranded_rows.mjs +1 -1
- package/tests/stuck_detector.mjs +14 -14
- package/tests/sweep_app_account.mjs +3 -3
- package/tests/task_cli.mjs +2 -2
- package/tests/task_detail_ui.mjs +11 -1
- package/tests/task_discipline_required.mjs +2 -2
- package/tests/task_list_paging.mjs +1 -1
- package/tests/task_visual_slots.mjs +2 -2
- package/tests/terms_acceptance.mjs +1 -1
- package/tests/terms_grandfather_db.mjs +1 -1
- package/tests/test_path_guard.mjs +1 -1
- package/tests/triage_development.mjs +1 -1
- package/tests/tweak_batch_apply.mjs +2 -2
- package/tests/tweak_land_heal.mjs +3 -3
- package/tests/tweak_unattended.mjs +3 -3
- package/tests/ui_design_skills.mjs +2 -2
- package/tests/unit_report_status.mjs +2 -2
- package/tests/unit_runner_serial.mjs +2 -2
- package/tests/unit_runner_teardown_abort.mjs +1 -1
- package/tests/update_channel.mjs +2 -2
- package/tests/update_channel_db.mjs +4 -4
- package/tests/update_subscription_engine.mjs +26 -26
- package/tests/update_sweep_home.mjs +14 -14
- package/tests/upgrade.mjs +11 -11
- package/tests/upgrade_artist_gate.mjs +4 -4
- package/tests/upgrade_commit_identity.mjs +2 -2
- package/tests/upgrade_migrate.mjs +7 -7
- package/tests/upgrade_operator.mjs +2 -2
- package/tests/upgrade_outcome.mjs +2 -2
- package/tests/upgrade_persist_pin.mjs +5 -5
- package/tests/upkeep_home.mjs +1 -1
- package/tests/version_close.mjs +2 -2
- package/tests/version_close_cli.mjs +2 -2
- package/tests/version_close_route.mjs +1 -1
- package/tests/version_literals.mjs +23 -23
- package/tests/visual_review.mjs +5 -5
- package/tests/wedge_remedy.mjs +5 -5
- package/tests/welcome_boot.mjs +116 -0
- package/tests/welcome_boot_browser.mjs +271 -0
- package/tests/wizard_born_first_board.mjs +3 -3
- package/tests/wizard_demo.mjs +1 -1
- package/tests/wizard_one_page.mjs +4 -3
- package/tests/wizard_physics.mjs +3 -1
- package/tests/wizard_physics_more.mjs +42 -3
- package/tests/work_title_wrap.mjs +1 -1
- package/tests/workflow_exec_paths.mjs +6 -6
- package/tests/worktree_claim_guard.mjs +1 -1
- package/tests/worktree_helper.mjs +2 -2
- package/tests/write_validation_gaps.mjs +3 -3
- package/scripts/gds/api.sh +0 -6
- package/scripts/gds/artifact-staleness.js +0 -267
- package/scripts/gds/audit-exports.js +0 -128
- package/scripts/gds/classify-discipline.js +0 -153
- package/scripts/gds/codemod-rename-src-gds.js +0 -145
- package/scripts/gds/coreB-carve-proof.sh +0 -725
- package/scripts/gds/goal-names.js +0 -102
- package/scripts/gds/rename-goals.js +0 -109
- package/scripts/gds/resolve-skill-model.js +0 -57
- package/scripts/gds/security-baseline-check.sh +0 -180
- package/scripts/gds/seed-adopt-tasks.js +0 -75
- package/scripts/gds/seed-api-contract-goal-tasks.js +0 -141
- package/scripts/gds/seed-board-room-tasks.js +0 -196
- package/scripts/gds/seed-bongos-app-tasks.js +0 -294
- package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +0 -81
- package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +0 -100
- package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +0 -307
- package/scripts/gds/seed-bongos-module-system-tasks.js +0 -346
- package/scripts/gds/seed-bongos-tasks.js +0 -214
- package/scripts/gds/seed-bongos-v1-seo-tasks.js +0 -104
- package/scripts/gds/seed-bv1-community-tasks.js +0 -131
- package/scripts/gds/seed-bv1-privacy-invites-tasks.js +0 -133
- package/scripts/gds/seed-bv1-profile-page-tasks.js +0 -161
- package/scripts/gds/seed-bv1-r01-delta-tasks.js +0 -154
- package/scripts/gds/seed-bv2-tweak-mode-tasks.js +0 -277
- package/scripts/gds/seed-gds-v4-tasks.js +0 -624
- package/scripts/gds/seed-governance-tasks.js +0 -340
- package/scripts/gds/seed-medusa-tasks.js +0 -440
- package/scripts/gds/seed-module-upstreaming.js +0 -219
- package/scripts/gds/seed-productization-tasks.js +0 -235
- package/scripts/gds/seed-project-admin-console-tasks.js +0 -88
- package/scripts/gds/seed-provisioning-tasks.js +0 -83
- package/scripts/gds/seed-strict-versioning-tasks.js +0 -275
- package/scripts/gds/seed-v2-world-tasks.js +0 -283
- package/scripts/gds/spike-task-map.js +0 -899
- package/scripts/migrate_cost_ledger.sh +0 -178
- package/scripts/status-probe.mjs +0 -213
- package/src/bongos/uptime-poller.js +0 -93
- package/tests/artifact_staleness.mjs +0 -207
- package/tests/goal_names.mjs +0 -120
- package/tests/government_fold_bench.mjs +0 -50
- package/tests/spike_task_map.mjs +0 -422
- package/tests/status-probe.mjs +0 -89
- /package/{scripts/gds → modules/raise}/CLAUDE.md +0 -0
- /package/scripts/{gds → bongos}/cloudbongos-token-isolation.conf +0 -0
- /package/scripts/{gds → bongos}/discipline-modes.json +0 -0
- /package/scripts/{gds → bongos}/retired-core-skills.json +0 -0
package/scripts/gds/fitness.js
CHANGED
|
@@ -1,1495 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// scripts/gds/fitness.js — @bongos-forwarder (task 1004848). Generated by
|
|
3
|
+
// scripts/bongos/codemod-rename-scripts-gds.js; do not edit.
|
|
4
|
+
// The real script is scripts/bongos/fitness.js. This forwarder keeps callers that still name
|
|
5
|
+
// the old path working, and warns once so they get repointed. Task 1003706 removes it.
|
|
2
6
|
'use strict';
|
|
3
|
-
|
|
4
|
-
//
|
|
5
|
-
// The ENFORCEMENT layer for the Cloud Bongos decoupling. A dependency-cruiser/ArchUnit-style gate that
|
|
6
|
-
// keeps the architecture from silently rotting back together. Each check is a pure function over
|
|
7
|
-
// the repo on disk returning { name, ok, hardFail, violations[], warnings[], note }. The CLI runs
|
|
8
|
-
// them all, prints a report, and exits non-zero on any hard failure. tests/fitness.mjs asserts
|
|
9
|
-
// each check passes, so the DB-free unit gate (run-unit-tests.js → the `unit` required check)
|
|
10
|
-
// enforces them on every PR — no new workflow needed.
|
|
11
|
-
//
|
|
12
|
-
// RATCHET, not big-bang. The structural epics that physically separate the core (R51 entrypoint
|
|
13
|
-
// #1190, R52 DB carve-out #1191, R54 module system #1193) are not built yet, so the codebase is
|
|
14
|
-
// still fused (every src/bongos/*.js shares the game's pg Pool via require('../db')). These checks
|
|
15
|
-
// therefore lock in the boundary DIRECTION now and fail only on NEW violations beyond a documented
|
|
16
|
-
// grandfather list; as the epics land they SHRINK the grandfather list. Module-level boundary
|
|
17
|
-
// enforcement (§4) tightens once R54 (#1193) gives us a module manifest to check against.
|
|
18
|
-
//
|
|
19
|
-
// Usage:
|
|
20
|
-
// node scripts/gds/fitness.js # run all checks, print report, exit 1 on any hard failure
|
|
21
|
-
// node scripts/gds/fitness.js --json # machine-readable report
|
|
22
|
-
|
|
23
|
-
const fs = require('node:fs');
|
|
24
|
-
const path = require('node:path');
|
|
25
|
-
const { execFileSync } = require('node:child_process');
|
|
26
|
-
const { checkRankGuards, checkModulePinKeysResolve } = require('./fitness-checks-route-pins.js'); // Checks 4 + 4b — carved out by task 1003192 (the 1,500-line ratchet)
|
|
27
|
-
const genApiDocs = require('./gen-api-docs'); // R12 (#1999): reuse the route model (readsBody/validated) that drives the OpenAPI spec
|
|
28
|
-
const { parseRoutineFrontmatter } = require('./run-routine'); // System 4 (ADR 0078): deterministic-routine boundary
|
|
29
|
-
const { filenameViolation, stemCollisions, numberCollisions, CORE_NS, INSTANCE_NS } = require('./migration-namespace'); // ADR 0108 §5: cross-repo migration namespacing
|
|
30
|
-
const { resolveCoreRoot, resolveInstanceRoot } = require('../../src/instance-config'); // ADR 0108 §1: configurable-root
|
|
31
|
-
|
|
32
|
-
// task 1003206 (goal 1000079): fitness.js was 2,004 lines. Four cohesive pieces now
|
|
33
|
-
// live beside it — the shared roots/walkers and three check clusters. They are
|
|
34
|
-
// IMPORTED (not registered by path) so the CHECKS array and module.exports below
|
|
35
|
-
// stay byte-identical to the single-file version every test was written against.
|
|
36
|
-
const { CORE_ROOT, INSTANCE_ROOT, MODULE_ROOTS, REPO_ROOT, keyTokenRe, rel, runChecks, walkJs, walkJsAllRoots } = require('./fitness-lib.js');
|
|
37
|
-
const { IDENTITY_SCAN_ALLOWED, IDENTITY_SCAN_EXCLUDE, IDENTITY_SCAN_EXTRA_FILES, IDENTITY_SCAN_EXTS, IDENTITY_SCAN_ROOTS, IDENTITY_SCAN_SKIP_DIRS, PROMPT_IDENTITY_LITERALS, checkDesignContract, checkKernelPromptsNoHardcodedIdentity, checkNeutralConfigsNoHostIdentity, collectIdentityFiles, scanPromptIdentity, stripCommentsForIdentity } = require('./fitness-checks-identity.js');
|
|
38
|
-
const { WRITE_VALIDATION_BASELINE, WRITE_VALIDATION_EXEMPT, checkWriteRoutesValidated, scanUnvalidatedWriteRoutes } = require('./fitness-checks-write-validation.js');
|
|
39
|
-
const { GOAL_VOCAB_CITATION, GOAL_VOCAB_LINE_SCOPED, GOAL_VOCAB_SURFACE, LIFECYCLE_DB_FILES, PRELAUNCH_SURFACE, RENAME_IDENTITY_RE, VOCAB_ALLOW, VOCAB_BANNED, VOCAB_CITATION, VOCAB_EXTS, VOCAB_HISTORICAL_REF, VOCAB_SURFACE, checkGoalMembershipVocabulary, checkGovernmentRenameIdentity, checkPrelaunchVocabulary, checkVocabularyWall, vocabFilesToScan } = require('./fitness-checks-vocabulary.js');
|
|
40
|
-
const { checkCoreRequiresExcludedConfig, checkCoreRequiresExcludedModule } = require('./fitness-checks-packaging.js'); // Checks 16 + 16b — carved out by task 1003825 (the 1,500-line ratchet)
|
|
41
|
-
const { FLAT_ERROR_BASELINE, checkErrorEnvelope, countFlatErrors, scanFlatErrorSites } = require('./fitness-checks-error-envelope.js'); // Check 17 — carved out by task 1003825
|
|
42
|
-
// ============================================================================
|
|
43
|
-
// Check 1 — core ↔ host/game import boundary (ADR 0062 §1 cut-line)
|
|
44
|
-
// ============================================================================
|
|
45
|
-
//
|
|
46
|
-
// The portable core (src/bongos/) must not import the HOST GAME runtime. After BV1.R49 the game
|
|
47
|
-
// module lives in modules/game/ (rooms, world, db, seats, public, migrations). The only game-
|
|
48
|
-
// related file that stays in src/ is src/preview-server.js (the game-only sandbox entrypoint).
|
|
49
|
-
// Imports into scripts/ (build tooling / engine) are NOT host-game coupling.
|
|
50
|
-
const HOST_GAME = [
|
|
51
|
-
/^modules\/game\//, // everything in the game module (moved from src/ by BV1.R49)
|
|
52
|
-
/^src\/preview-server\.js$/, // game-only sandbox entrypoint (stays in src/)
|
|
53
|
-
];
|
|
54
|
-
// Empty as of R52/#1191 — the core owns its pool (src/bongos/pool.js) and no longer imports the
|
|
55
|
-
// game's db helper. The boundary now enforces with ZERO grandfathered exceptions.
|
|
56
|
-
const GRANDFATHERED = new Set([]);
|
|
57
|
-
const REQUIRE_RE = /require\(\s*['"](\.\.?\/[^'"]+)['"]\s*\)/g;
|
|
58
|
-
|
|
59
|
-
function resolvesToHostGame(fromAbsFile, spec) {
|
|
60
|
-
const abs = path.resolve(path.dirname(fromAbsFile), spec);
|
|
61
|
-
const r = rel(abs);
|
|
62
|
-
for (const cand of [r, r + '.js', r.replace(/\/$/, '') + '/index.js']) {
|
|
63
|
-
if (GRANDFATHERED.has(cand)) return null; // allowed (and not a violation)
|
|
64
|
-
if (HOST_GAME.some((re) => re.test(cand))) return cand;
|
|
65
|
-
}
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function checkCoreHostBoundary() {
|
|
70
|
-
const coreDir = path.join(REPO_ROOT, 'src', 'bongos');
|
|
71
|
-
const violations = [];
|
|
72
|
-
for (const abs of walkJs(coreDir)) {
|
|
73
|
-
// scan line-by-line, skipping comment lines so a require(...) quoted in a doc comment
|
|
74
|
-
// (e.g. explaining the boundary) is never mistaken for a real import.
|
|
75
|
-
for (const raw of fs.readFileSync(abs, 'utf8').split('\n')) {
|
|
76
|
-
const trimmed = raw.trim();
|
|
77
|
-
if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*')) continue;
|
|
78
|
-
let m;
|
|
79
|
-
REQUIRE_RE.lastIndex = 0;
|
|
80
|
-
while ((m = REQUIRE_RE.exec(raw))) {
|
|
81
|
-
const target = resolvesToHostGame(abs, m[1]);
|
|
82
|
-
if (target) violations.push(`${rel(abs)} → require('${m[1]}') reaches host-game code (${target}) — the core must not import the game runtime (ADR 0062 §1).`);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return {
|
|
87
|
-
name: 'core↔host import boundary',
|
|
88
|
-
ok: violations.length === 0,
|
|
89
|
-
hardFail: violations.length > 0,
|
|
90
|
-
violations,
|
|
91
|
-
warnings: [],
|
|
92
|
-
note: `src/bongos/ must not import the host game runtime (grandfathered: ${[...GRANDFATHERED].join(', ') || 'none'} — severed by R52/#1191).`,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// ============================================================================
|
|
97
|
-
// Check 2 — root CLAUDE.md size budget + charter presence (ADR 0061)
|
|
98
|
-
// ============================================================================
|
|
99
|
-
const ROOT_HARD_MAX = 300; // ceiling: the always-loaded file must never balloon past this. Ratcheted
|
|
100
|
-
// 360→310 when task 1226 generated the §13 session-log index (was a ~58-line
|
|
101
|
-
// hand-maintained list), then 310→300 when task 1283 trimmed the quick-nav
|
|
102
|
-
// table + §2/§8/§9/§10/§12 verbose prose down to ~294 lines. Lower further as
|
|
103
|
-
// more detail relocates to nested docs / ADRs (ADR 0061).
|
|
104
|
-
const ROOT_TARGET = 200; // the charter's stated aim; keep ratcheting toward it.
|
|
105
|
-
|
|
106
|
-
// The line count is a structure/readability proxy; the cost paid EVERY session is
|
|
107
|
-
// characters/tokens. A 600-char quick-nav row is one line but ~150 tokens, so
|
|
108
|
-
// within-line bloat slips past ROOT_HARD_MAX entirely (exactly what task 1283
|
|
109
|
-
// trimmed). Guard the real cost too (task 1286). Ratcheted just above the
|
|
110
|
-
// post-1283 size (~39.5K chars / ~9.9K tok); lower alongside ROOT_HARD_MAX as
|
|
111
|
-
// detail relocates to nested docs / ADRs.
|
|
112
|
-
const ROOT_CHAR_HARD_MAX = 42000; // ~10.5K tokens — the always-loaded file must never balloon past this.
|
|
113
|
-
const ROOT_CHAR_TARGET = 32000; // ~8K tokens — aspirational, mirrors the ~200-line aim.
|
|
114
|
-
const estTokens = (n) => Math.round(n / 4); // ~4 chars/token for markdown prose.
|
|
115
|
-
|
|
116
|
-
// Where the charter BODY lives since task 1003687. It is guidance for EDITING a
|
|
117
|
-
// CLAUDE.md, so it is paths-scoped (`paths:` frontmatter, same mechanism as
|
|
118
|
-
// .claude/rules/hook-authoring.md) and costs nothing in the sessions — the large
|
|
119
|
-
// majority — that never open one. The kernel keeps the heading and a pointer.
|
|
120
|
-
const CHARTER_RULE_REL = '.claude/rules/claudemd-authoring.md';
|
|
121
|
-
|
|
122
|
-
function checkClaudeMdBudget(opts = {}) {
|
|
123
|
-
const p = path.join(INSTANCE_ROOT, 'CLAUDE.md'); // the root CLAUDE.md is INSTANCE content (materialized per instance; ADR 0108)
|
|
124
|
-
const text = opts.text != null ? opts.text : fs.readFileSync(p, 'utf8');
|
|
125
|
-
const lines = text.split('\n').length;
|
|
126
|
-
const violations = [];
|
|
127
|
-
const warnings = [];
|
|
128
|
-
if (lines > ROOT_HARD_MAX) {
|
|
129
|
-
violations.push(`CLAUDE.md is ${lines} lines — over the ${ROOT_HARD_MAX}-line hard ceiling. It loads in full every session; relocate detail to a nested CLAUDE.md / ADR / recipe (ADR 0061).`);
|
|
130
|
-
} else if (lines > ROOT_TARGET) {
|
|
131
|
-
warnings.push(`CLAUDE.md is ${lines} lines — over the ~${ROOT_TARGET}-line target (still under the ${ROOT_HARD_MAX} ceiling). Relocate more detail to nested CLAUDE.md / ADRs / recipes (ADR 0061), then lower ROOT_HARD_MAX as it shrinks.`);
|
|
132
|
-
}
|
|
133
|
-
const chars = text.length;
|
|
134
|
-
const tok = estTokens(chars);
|
|
135
|
-
if (chars > ROOT_CHAR_HARD_MAX) {
|
|
136
|
-
violations.push(`CLAUDE.md is ${chars} chars (~${tok} tokens) — over the ${ROOT_CHAR_HARD_MAX}-char (~${estTokens(ROOT_CHAR_HARD_MAX)}-token) hard ceiling. The line count may be fine, but the per-session token cost is not — trim verbose prose WITHIN lines (long quick-nav rows, restated rationale), not just whole lines (ADR 0061).`);
|
|
137
|
-
} else if (chars > ROOT_CHAR_TARGET) {
|
|
138
|
-
warnings.push(`CLAUDE.md is ${chars} chars (~${tok} tokens) — over the ~${ROOT_CHAR_TARGET}-char (~${estTokens(ROOT_CHAR_TARGET)}-token) target. This is the true per-session cost; within-line bloat (a 600-char table row is one line) escapes the line check. Trim prose, then lower ROOT_CHAR_HARD_MAX.`);
|
|
139
|
-
}
|
|
140
|
-
if (!text.includes('## Working with this file (content charter)')) {
|
|
141
|
-
violations.push('CLAUDE.md is missing the content-charter section (ADR 0061) — the per-line test + "what goes where" table must stay.');
|
|
142
|
-
} else {
|
|
143
|
-
// Task 1003687 relocated the charter BODY to a paths-scoped rule, so the kernel
|
|
144
|
-
// keeps the heading and a pointer. That makes the heading cheap to fake: a section
|
|
145
|
-
// with nothing behind it satisfies a substring check while the rules it names are
|
|
146
|
-
// gone. So the charter must resolve to something — either inline here, or through a
|
|
147
|
-
// pointer whose target actually exists and still carries the two rules + the table.
|
|
148
|
-
const namesRule = text.includes(CHARTER_RULE_REL);
|
|
149
|
-
const inlineCharter = text.includes('Per-line test:');
|
|
150
|
-
if (namesRule) {
|
|
151
|
-
const rulePath = path.join(INSTANCE_ROOT, CHARTER_RULE_REL); // .claude/ is materialized INSTANCE content (ADR 0108 §3)
|
|
152
|
-
if (!fs.existsSync(rulePath)) {
|
|
153
|
-
violations.push(`CLAUDE.md points its content charter at ${CHARTER_RULE_REL}, but that file does not exist — a pointer to nothing is worse than no pointer (ADR 0061 / task 1003687).`);
|
|
154
|
-
} else {
|
|
155
|
-
const rule = fs.readFileSync(rulePath, 'utf8');
|
|
156
|
-
const missing = [];
|
|
157
|
-
if (!/^---\r?\n[\s\S]*?\bpaths:[\s\S]*?["']\*\*\/CLAUDE\.md["'][\s\S]*?^---$/m.test(rule)) {
|
|
158
|
-
missing.push('`paths:` frontmatter matching `**/CLAUDE.md` (without it the rule never loads, and the charter is simply gone)');
|
|
159
|
-
}
|
|
160
|
-
if (!rule.includes('Per-line test:')) missing.push('the per-line test');
|
|
161
|
-
if (!rule.includes('## What goes where')) missing.push('the "what goes where" table');
|
|
162
|
-
if (missing.length) {
|
|
163
|
-
violations.push(`${CHARTER_RULE_REL} is missing ${missing.join(', ')} — the kernel delegates the charter to it, so the charter is only as real as that file (ADR 0061 / task 1003687).`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
} else if (!inlineCharter) {
|
|
167
|
-
violations.push('The CLAUDE.md content-charter section is hollow — it has the heading but neither the per-line test inline nor a pointer to `' + CHARTER_RULE_REL + '`. The heading exists to make the rules findable; on its own it only satisfies this check (ADR 0061).');
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return { name: 'root CLAUDE.md budget + charter', ok: violations.length === 0, hardFail: violations.length > 0, violations, warnings, note: `≤ ${ROOT_HARD_MAX} lines / ${ROOT_CHAR_HARD_MAX} chars (~${estTokens(ROOT_CHAR_HARD_MAX)} tok); targets ~${ROOT_TARGET} lines / ~${estTokens(ROOT_CHAR_TARGET)} tok; charter resolves (inline or via ${CHARTER_RULE_REL}).` };
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// ============================================================================
|
|
174
|
-
// Check 3 — nested per-module CLAUDE.md presence for high-traffic dirs (ADR 0061)
|
|
175
|
-
// ============================================================================
|
|
176
|
-
const HIGH_TRAFFIC = ['src/bongos', 'src/bongos/routes', 'scripts/gds'];
|
|
177
|
-
|
|
178
|
-
function checkNestedDocsPresent() {
|
|
179
|
-
const violations = [];
|
|
180
|
-
for (const dir of HIGH_TRAFFIC) {
|
|
181
|
-
// HIGH_TRAFFIC dirs (src/bongos, src/bongos/routes, scripts/gds) are CORE-package dirs — resolve
|
|
182
|
-
// against the core root, not the instance repo (ADR 0108 §Consequences #4).
|
|
183
|
-
const doc = path.join(CORE_ROOT, dir, 'CLAUDE.md');
|
|
184
|
-
if (!fs.existsSync(doc)) violations.push(`${dir}/CLAUDE.md is missing — high-traffic dirs must carry a nested altitude map (ADR 0061).`);
|
|
185
|
-
}
|
|
186
|
-
return { name: 'nested CLAUDE.md presence', ok: violations.length === 0, hardFail: violations.length > 0, violations, warnings: [], note: `present for: ${HIGH_TRAFFIC.join(', ')}.` };
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// ============================================================================
|
|
190
|
-
// Check 5 — generated artifacts are fresh (Path C enforces Path B; ADR 0063 + ADR 0062 §8)
|
|
191
|
-
// ============================================================================
|
|
192
|
-
// Deterministic file-reads with a `--check` mode (regenerate in-memory, diff, exit non-zero on
|
|
193
|
-
// drift). This gate fails a PR that committed a stale artifact so the "generate, don't hand-maintain"
|
|
194
|
-
// contract can't rot.
|
|
195
|
-
// ADR 0110 (task 1926): docs/repo-map.md + docs/session-log-index.md are now GITIGNORED and
|
|
196
|
-
// regenerated at deploy/box-fetch (the gen-atlas.js model), so parallel branches never collide on
|
|
197
|
-
// them — and there is no committed copy to gate. Their generators are DUAL-DUTY, though: each also
|
|
198
|
-
// refreshes a TRACKED embedded block (the nested CLAUDE.md symbol blocks; the CLAUDE.md §13 snippet).
|
|
199
|
-
// Those blocks stay committed, so we gate the BLOCK bucket HARD via `--check-block`. A naive `--check`
|
|
200
|
-
// here would false-fail every PR (the gitignored whole file is absent from a clean checkout, so it
|
|
201
|
-
// always reads as "would change"); `--check-block` is the exact, non-noisy gate. (docs/file-map.md +
|
|
202
|
-
// the OpenAPI docs are still fully committed and unchanged by ADR 0110 — they keep the plain --check.)
|
|
203
|
-
function checkGeneratedArtifactsFresh() {
|
|
204
|
-
const violations = [];
|
|
205
|
-
try {
|
|
206
|
-
execFileSync(process.execPath, [path.join(__dirname, 'gen-repo-map.js'), '--check-block'], { cwd: REPO_ROOT, stdio: 'pipe' });
|
|
207
|
-
} catch {
|
|
208
|
-
violations.push('The tracked nested-doc symbol blocks (src/bongos/CLAUDE.md, src/bongos/routes/CLAUDE.md) are STALE — run `node scripts/gds/gen-repo-map.js` and commit (ADR 0063 / ADR 0110). NB docs/repo-map.md itself is gitignored + deploy-regenerated, not gated here.');
|
|
209
|
-
}
|
|
210
|
-
try {
|
|
211
|
-
execFileSync(process.execPath, [path.join(__dirname, 'gen-session-index.js'), '--check-block'], { cwd: REPO_ROOT, stdio: 'pipe' });
|
|
212
|
-
} catch {
|
|
213
|
-
violations.push('The tracked CLAUDE.md §13 recent-sessions snippet is STALE — run `node scripts/gds/gen-session-index.js` and commit (ADR 0062 §8 / ADR 0110). NB docs/session-log-index.md itself is gitignored + deploy-regenerated, not gated here.');
|
|
214
|
-
}
|
|
215
|
-
try {
|
|
216
|
-
// task 1002515 (criterion `accessibility-fluency-profile`, clause 2): the CLAUDE.md §2
|
|
217
|
-
// fallback posture is generated from the interaction knob's own defaults, so the kernel
|
|
218
|
-
// and modules/builder-settings/interaction-prefs.js cannot drift into two copies of one
|
|
219
|
-
// rule — which is what they were. Fully tracked (unlike the ADR 0110 pair above), so a
|
|
220
|
-
// plain --check is the right gate.
|
|
221
|
-
execFileSync(process.execPath, [path.join(__dirname, 'gen-interaction-posture.js'), '--check'], { cwd: REPO_ROOT, stdio: 'pipe' });
|
|
222
|
-
} catch {
|
|
223
|
-
violations.push('The CLAUDE.md §2 interaction-posture block is STALE — it is generated from modules/builder-settings/interaction-prefs.js. Run `node scripts/gds/gen-interaction-posture.js` and commit (task 1002515).');
|
|
224
|
-
}
|
|
225
|
-
try {
|
|
226
|
-
execFileSync(process.execPath, [path.join(__dirname, 'gen-file-map.js'), '--check'], { cwd: REPO_ROOT, stdio: 'pipe' });
|
|
227
|
-
} catch {
|
|
228
|
-
violations.push('docs/file-map.md generated sections (.claude/skills/, .claude/scheduled-tasks/) are STALE, a skill/routine has no note in docs/file-map.notes.json, or a directory under modules/ has no file-map entry at all — run `node scripts/gds/gen-file-map.js --check` for the exact list, then fix and commit (ADR 0066; module coverage: task 1004066).');
|
|
229
|
-
}
|
|
230
|
-
try {
|
|
231
|
-
// Also structurally validates the spec (exit 1 on invalid OpenAPI 3.1) beyond the drift check (exit 2). Task 1918.
|
|
232
|
-
execFileSync(process.execPath, [path.join(__dirname, 'gen-api-docs.js'), '--check'], { cwd: REPO_ROOT, stdio: 'pipe' });
|
|
233
|
-
} catch {
|
|
234
|
-
violations.push('docs/api/openapi.json + docs/api-reference.md + docs/routes-permissions.md are STALE (or the spec is not valid OpenAPI 3.1) — run `node scripts/gds/gen-api-docs.js` and commit (task 1918).');
|
|
235
|
-
}
|
|
236
|
-
try {
|
|
237
|
-
// task 1003556: the copy registry's rows carry LINE NUMBERS, so editing any scanned
|
|
238
|
-
// UI file stales it. It was covered only by ship-check's OPTIONAL step, which a
|
|
239
|
-
// builder has to remember to run — so the first signal was CI failing on the PR's
|
|
240
|
-
// MERGE ref, where the shift is hardest to attribute. Gated here so a local fitness
|
|
241
|
-
// run says so first.
|
|
242
|
-
execFileSync(process.execPath, [path.join(__dirname, 'copy-inventory.js'), '--check'], { cwd: REPO_ROOT, stdio: 'pipe' });
|
|
243
|
-
} catch {
|
|
244
|
-
violations.push('docs/copy-registry.json + docs/copy-inventory.md are STALE — every row carries a line number, so editing any scanned UI file shifts them. Run `node scripts/gds/copy-inventory.js` and commit (task 1003556).');
|
|
245
|
-
}
|
|
246
|
-
try {
|
|
247
|
-
// task 1004314 (BV2.TW02): the page inventory is the key Tweak Mode's page status,
|
|
248
|
-
// claims and pay join on, so a page added, renamed or retitled without it would
|
|
249
|
-
// be a page the chain cannot see. --check also fails on a duplicate or malformed id.
|
|
250
|
-
execFileSync(process.execPath, [path.join(__dirname, 'page-inventory.js'), '--check'], { cwd: REPO_ROOT, stdio: 'pipe' });
|
|
251
|
-
} catch {
|
|
252
|
-
violations.push('docs/page-inventory.json + docs/page-inventory.md are STALE (or two pages claim one id) — a page was added, renamed, retitled or changed its scripts/states. Run `node scripts/gds/page-inventory.js` and commit (task 1004314).');
|
|
253
|
-
}
|
|
254
|
-
// NB the role packs' responsibility blocks are generated too, but their freshness
|
|
255
|
-
// is asserted by role-pack-guard.js — one check owns "the packs are correct".
|
|
256
|
-
return { name: 'generated artifacts fresh', ok: violations.length === 0, hardFail: violations.length > 0, violations, warnings: [], note: 'Tracked generated content matches source: nested CLAUDE.md symbol blocks (code) + the CLAUDE.md §13 snippet (sessions) via --check-block, plus the CLAUDE.md §2 interaction-posture block (the knob defaults), docs/file-map.md skills/scheduled-tasks sections, docs/api/openapi.json + api-reference.md (API), docs/copy-registry.json + copy-inventory.md (the reader-facing copy, task 1003556) and docs/page-inventory.json + page-inventory.md (every page and its stable id, task 1004314). The gitignored docs/repo-map.md + docs/session-log-index.md are deploy-regenerated (ADR 0110), not gated here.' };
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// ---- deterministic cron routine boundary (System 4 / ADR 0078) -------------
|
|
260
|
-
//
|
|
261
|
-
// A `mode: deterministic` routine runs as plain node via run-routine.js — NO
|
|
262
|
-
// model session reads its SKILL body. So that body must not rot back into a
|
|
263
|
-
// wrapped session: it may not instruct a model to mutate (Edit/Write/git
|
|
264
|
-
// push/commit/deploy) or synthesize free text, and its documented commands must
|
|
265
|
-
// not diverge from its declared steps. Keeps the markdown-graveyard pattern out.
|
|
266
|
-
|
|
267
|
-
const SCHEDULED_TASKS_DIR = path.join(INSTANCE_ROOT, '.claude', 'scheduled-tasks'); // .claude/ is materialized INSTANCE content (ADR 0108 §3)
|
|
268
|
-
|
|
269
|
-
// Judgment/mutation instructions illegal in a deterministic body. Negated
|
|
270
|
-
// mentions ("never pushes", "does NOT edit") are descriptive boundaries — allowed.
|
|
271
|
-
const JUDGMENT_PATTERNS = [
|
|
272
|
-
{ re: /\bgit\s+(push|commit|add)\b/i, label: 'a git push/commit/add' },
|
|
273
|
-
{ re: /deploy\.sh\b/i, label: 'a deploy.sh invocation' },
|
|
274
|
-
{ re: /`(Edit|Write|MultiEdit|NotebookEdit)`/, label: 'an Edit/Write tool instruction' },
|
|
275
|
-
{ re: /\bsynthesi[sz]e\b/i, label: 'free-text synthesis' },
|
|
276
|
-
{ re: /\b(write|compose|draft)\s+(a|an|the)\s+(summary|report|analysis|narrative|note)\b/i, label: 'free-text synthesis' },
|
|
277
|
-
];
|
|
278
|
-
const NEGATION_RE = /\b(never|not|no|without|cannot|can't|don'?t|doesn'?t|won'?t)\b/i;
|
|
279
|
-
|
|
280
|
-
// Pure: scan one routine's parsed (mode, steps, body). Returns violation strings.
|
|
281
|
-
// Only inspects deterministic routines; others return []. Exported for tests.
|
|
282
|
-
function scanDeterministicBody(name, { mode, steps, body }) {
|
|
283
|
-
if (mode !== 'deterministic') return [];
|
|
284
|
-
const violations = [];
|
|
285
|
-
if (!steps || steps.length === 0) {
|
|
286
|
-
violations.push(`${name}: mode: deterministic but no steps: — run-routine.js would launch nothing (ADR 0078).`);
|
|
287
|
-
}
|
|
288
|
-
const text = String(body == null ? '' : body);
|
|
289
|
-
for (const raw of text.split('\n')) {
|
|
290
|
-
const line = raw.trim();
|
|
291
|
-
if (!line || NEGATION_RE.test(line)) continue; // skip blank + negated (boundary) lines
|
|
292
|
-
for (const p of JUDGMENT_PATTERNS) {
|
|
293
|
-
if (p.re.test(line)) {
|
|
294
|
-
violations.push(`${name}: deterministic SKILL body contains ${p.label} ("${line.slice(0, 70)}") — it runs as plain node with no model; move remediation/judgment to a separate claimed task (ADR 0078).`);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
// Divergence: every `node …` command in a fenced code block must be a declared step.
|
|
299
|
-
const stepCmds = (steps || []).map((s) => String(s.command).replace(/\s+/g, ' ').trim());
|
|
300
|
-
for (const fence of text.match(/```[\s\S]*?```/g) || []) {
|
|
301
|
-
for (const fl of fence.split('\n')) {
|
|
302
|
-
const cmd = fl.trim().replace(/\s+/g, ' ');
|
|
303
|
-
if (!cmd.startsWith('node ')) continue;
|
|
304
|
-
if (!stepCmds.some((s) => cmd === s || cmd.startsWith(s) || s.startsWith(cmd))) {
|
|
305
|
-
violations.push(`${name}: deterministic SKILL body documents \`${cmd.slice(0, 70)}\` which is not in its steps: — prose and steps must not diverge (ADR 0078).`);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
return violations;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
function checkDeterministicRoutines() {
|
|
313
|
-
const violations = [];
|
|
314
|
-
let detCount = 0;
|
|
315
|
-
let dirs = [];
|
|
316
|
-
try {
|
|
317
|
-
dirs = fs.readdirSync(SCHEDULED_TASKS_DIR, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
318
|
-
} catch (_) { /* no scheduled-tasks dir → nothing to check */ }
|
|
319
|
-
for (const name of dirs) {
|
|
320
|
-
let md;
|
|
321
|
-
try { md = fs.readFileSync(path.join(SCHEDULED_TASKS_DIR, name, 'SKILL.md'), 'utf8'); } catch (_) { continue; }
|
|
322
|
-
const { mode, steps } = parseRoutineFrontmatter(md);
|
|
323
|
-
if (mode !== 'deterministic') continue;
|
|
324
|
-
detCount += 1;
|
|
325
|
-
const body = md.replace(/^---\n[\s\S]*?\n---\n?/, ''); // strip frontmatter
|
|
326
|
-
violations.push(...scanDeterministicBody(name, { mode, steps, body }));
|
|
327
|
-
}
|
|
328
|
-
return {
|
|
329
|
-
name: 'deterministic cron routines (ADR 0078)',
|
|
330
|
-
ok: violations.length === 0,
|
|
331
|
-
hardFail: violations.length > 0,
|
|
332
|
-
violations,
|
|
333
|
-
warnings: [],
|
|
334
|
-
note: `${detCount} mode:deterministic routine(s): steps declared, no judgment instructions, prose↔steps aligned.`,
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// ============================================================================
|
|
339
|
-
// Check 7/8 — module boundary (the one-way rule, ADR 0083 / design 04§3)
|
|
340
|
-
// ============================================================================
|
|
341
|
-
//
|
|
342
|
-
// The module system's one-way rule: a module imports ONLY src/module-api.js (the
|
|
343
|
-
// published doorway); the core NEVER imports a module; a module NEVER imports a
|
|
344
|
-
// sibling module. These two checks enforce it.
|
|
345
|
-
//
|
|
346
|
-
// Both were GREEN through the strangler: the first two moved modules (M07/M08)
|
|
347
|
-
// imported only the doorway, and the core imported neither. The boundary
|
|
348
|
-
// shipped in WARN mode so a half-moved module mid-migration couldn't red the
|
|
349
|
-
// build; BV1.R45 (task 1414) flips it to ENFORCING now that the first move
|
|
350
|
-
// (M07) proved clean — the monotonic ratchet (ADR 0062 §9 / design
|
|
351
|
-
// 04§3). A NEW cross-boundary import is now a red build; warn-mode is gone.
|
|
352
|
-
let MODULE_BOUNDARY_ENFORCING = true;
|
|
353
|
-
const MODULE_API_REL = 'src/module-api.js';
|
|
354
|
-
|
|
355
|
-
// If `spec` (a relative require) from `fromAbsFile` resolves into modules/<key>/,
|
|
356
|
-
// return <key>; else null. Pure path math — no fs.
|
|
357
|
-
function resolvesToModule(fromAbsFile, spec) {
|
|
358
|
-
const abs = path.resolve(path.dirname(fromAbsFile), spec);
|
|
359
|
-
const r = rel(abs);
|
|
360
|
-
const m = /^modules\/([^/]+)(\/|$)/.exec(r);
|
|
361
|
-
return m ? m[1] : null;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
// The module a core/module file belongs to, or null if it isn't under modules/.
|
|
365
|
-
function moduleOwnerOf(absFile) {
|
|
366
|
-
const m = /^modules\/([^/]+)\//.exec(rel(absFile));
|
|
367
|
-
return m ? m[1] : null;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
// For a require `spec` inside a MODULE file, return a violation string or null.
|
|
371
|
-
// Allowed: src/module-api.js (the doorway), intra-module relatives, and bare
|
|
372
|
-
// (npm/node) specs. Forbidden: deep core imports + sibling-module imports.
|
|
373
|
-
function moduleImportViolation(fromAbsFile, spec) {
|
|
374
|
-
const ownKey = moduleOwnerOf(fromAbsFile);
|
|
375
|
-
if (!ownKey) return null; // not a module file
|
|
376
|
-
const absTarget = path.resolve(path.dirname(fromAbsFile), spec);
|
|
377
|
-
const r = rel(absTarget);
|
|
378
|
-
// resolve possible file forms
|
|
379
|
-
const forms = [r, r + '.js', r.replace(/\/$/, '') + '/index.js'];
|
|
380
|
-
if (forms.includes(MODULE_API_REL)) return null; // the doorway — allowed
|
|
381
|
-
const otherKey = (() => { const m = /^modules\/([^/]+)(\/|$)/.exec(r); return m ? m[1] : null; })();
|
|
382
|
-
if (otherKey) {
|
|
383
|
-
if (otherKey === ownKey) return null; // intra-module — allowed
|
|
384
|
-
return `${rel(fromAbsFile)} → require('${spec}') reaches sibling module "${otherKey}" — modules must not import each other (use a kernel seam; ADR 0083).`;
|
|
385
|
-
}
|
|
386
|
-
if (/^src\//.test(r)) {
|
|
387
|
-
return `${rel(fromAbsFile)} → require('${spec}') reaches core internals (${r}) — a module may import only the published doorway src/module-api.js (ADR 0083).`;
|
|
388
|
-
}
|
|
389
|
-
return null; // outside the repo (node/npm) — not our concern
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
function checkCoreNeverImportsModule() {
|
|
393
|
-
const findings = [];
|
|
394
|
-
const roots = [path.join(REPO_ROOT, 'src'), path.join(REPO_ROOT, 'server.js')];
|
|
395
|
-
for (const root of roots) {
|
|
396
|
-
for (const abs of walkJs(root)) {
|
|
397
|
-
if (moduleOwnerOf(abs)) continue; // module files are scanned by the other check
|
|
398
|
-
if (HOST_GAME.some((re) => re.test(rel(abs)))) continue; // game-owned files that live in src/ (e.g. preview-server.js) may import game module
|
|
399
|
-
for (const raw of fs.readFileSync(abs, 'utf8').split('\n')) {
|
|
400
|
-
const t = raw.trim();
|
|
401
|
-
if (t.startsWith('//') || t.startsWith('*') || t.startsWith('/*')) continue;
|
|
402
|
-
let m; REQUIRE_RE.lastIndex = 0;
|
|
403
|
-
while ((m = REQUIRE_RE.exec(raw))) {
|
|
404
|
-
const key = resolvesToModule(abs, m[1]);
|
|
405
|
-
if (key) findings.push(`${rel(abs)} → require('${m[1]}') reaches module "${key}" — the core must never import a module (ADR 0083).`);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
const enforcing = MODULE_BOUNDARY_ENFORCING;
|
|
411
|
-
return {
|
|
412
|
-
name: 'core never imports a module',
|
|
413
|
-
ok: findings.length === 0,
|
|
414
|
-
hardFail: enforcing && findings.length > 0,
|
|
415
|
-
violations: enforcing ? findings : [],
|
|
416
|
-
warnings: enforcing ? [] : findings,
|
|
417
|
-
note: `core (src/, server.js) must not require modules/* — ${enforcing ? 'ENFORCING' : 'warn-mode until BV1.R45'} (ADR 0083).`,
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
function checkModulesImportOnlyApi() {
|
|
422
|
-
const findings = [];
|
|
423
|
-
for (const abs of walkJsAllRoots('modules')) { // modules ship from BOTH roots (ADR 0108 §Consequences #4)
|
|
424
|
-
for (const raw of fs.readFileSync(abs, 'utf8').split('\n')) {
|
|
425
|
-
const t = raw.trim();
|
|
426
|
-
if (t.startsWith('//') || t.startsWith('*') || t.startsWith('/*')) continue;
|
|
427
|
-
let m; REQUIRE_RE.lastIndex = 0;
|
|
428
|
-
while ((m = REQUIRE_RE.exec(raw))) {
|
|
429
|
-
const v = moduleImportViolation(abs, m[1]);
|
|
430
|
-
if (v) findings.push(v);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
const enforcing = MODULE_BOUNDARY_ENFORCING;
|
|
435
|
-
return {
|
|
436
|
-
name: 'modules import only the published API',
|
|
437
|
-
ok: findings.length === 0,
|
|
438
|
-
hardFail: enforcing && findings.length > 0,
|
|
439
|
-
violations: enforcing ? findings : [],
|
|
440
|
-
warnings: enforcing ? [] : findings,
|
|
441
|
-
note: `modules/** may require only src/module-api.js (no deep core, no sibling) — ${enforcing ? 'ENFORCING' : 'warn-mode until BV1.R45'} (ADR 0083).`,
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
// ============================================================================
|
|
446
|
-
// Check 9 — the goal scope map imports PROTECTED_GLOBS, never re-declares it
|
|
447
|
-
// (ADR 0086 §7; the SEC #863 "second list that drifts" failure mode)
|
|
448
|
-
// ============================================================================
|
|
449
|
-
//
|
|
450
|
-
// src/bongos/module-scope-map.js (BV1.R54) derives each module's `protected` flag
|
|
451
|
-
// from PROTECTED_GLOBS. That derivation is only trustworthy if it reads the ONE
|
|
452
|
-
// source (permission-path-check.js) — a hand-copied second list would silently
|
|
453
|
-
// drift from the real protected set and quietly de-protect a module. This check
|
|
454
|
-
// reds the build if the scope map stops importing PROTECTED_GLOBS, or copies it.
|
|
455
|
-
const SCOPE_MAP_REL = 'src/bongos/module-scope-map.js';
|
|
456
|
-
|
|
457
|
-
// Pure: scan the scope-map source for the import contract. Exported for the
|
|
458
|
-
// "actually catches a violation" test (mirrors scanDeterministicBody).
|
|
459
|
-
function scanScopeMapSource(src) {
|
|
460
|
-
const violations = [];
|
|
461
|
-
const text = String(src || '');
|
|
462
|
-
const importsFrom = /require\(\s*['"]\.\/permission-path-check['"]\s*\)/.test(text);
|
|
463
|
-
const namesIt = /\bPROTECTED_GLOBS\b/.test(text);
|
|
464
|
-
if (!importsFrom || !namesIt) {
|
|
465
|
-
violations.push(`${SCOPE_MAP_REL} must IMPORT PROTECTED_GLOBS from ./permission-path-check and derive \`protected\` from it — never hand-maintain a second protected list (ADR 0086 §7).`);
|
|
466
|
-
}
|
|
467
|
-
if (/\b(?:const|let|var)\s+PROTECTED_GLOBS\s*=/.test(text)) {
|
|
468
|
-
violations.push(`${SCOPE_MAP_REL} re-declares PROTECTED_GLOBS — it must import the single source from permission-path-check.js, not copy it (ADR 0086 §7; the SEC #863 second-list failure mode).`);
|
|
469
|
-
}
|
|
470
|
-
return violations;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
function checkScopeMapImportsProtected() {
|
|
474
|
-
const abs = path.join(REPO_ROOT, SCOPE_MAP_REL);
|
|
475
|
-
let src = null;
|
|
476
|
-
try { src = fs.readFileSync(abs, 'utf8'); } catch (_) { /* absent → skip */ }
|
|
477
|
-
// Absent → clean pass: the scope map is a BV1.R54 deliverable; until it exists
|
|
478
|
-
// there is no import contract to enforce (its own unit test asserts existence).
|
|
479
|
-
const violations = src == null ? [] : scanScopeMapSource(src);
|
|
480
|
-
return {
|
|
481
|
-
name: 'scope map imports PROTECTED_GLOBS (ADR 0086)',
|
|
482
|
-
ok: violations.length === 0,
|
|
483
|
-
hardFail: violations.length > 0,
|
|
484
|
-
violations,
|
|
485
|
-
warnings: [],
|
|
486
|
-
note: src == null
|
|
487
|
-
? `${SCOPE_MAP_REL} absent — skipped (created by BV1.R54).`
|
|
488
|
-
: `${SCOPE_MAP_REL} derives \`protected\` from the imported PROTECTED_GLOBS (single source; no copied list).`,
|
|
489
|
-
};
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
// ============================================================================
|
|
493
|
-
// Check 10 — core carries no module-specific code (ADR 0083 §Decision #4 / design 04§3)
|
|
494
|
-
// ============================================================================
|
|
495
|
-
//
|
|
496
|
-
// The module-system MACHINERY (the doorway + loader + seam registry) must stay
|
|
497
|
-
// module-AGNOSTIC: it discovers, validates, and mounts modules uniformly and may
|
|
498
|
-
// never special-case one by name. The import checks (Check 7/8) stop a module's
|
|
499
|
-
// CODE from being reached by `require`; this stops a module's IDENTITY from being
|
|
500
|
-
// hardcoded into the kernel (`if (key === 'art-pipeline') …`, a copied module helper,
|
|
501
|
-
// a registry entry that should have moved out). "No module-specific code" is
|
|
502
|
-
// operationalized as the one drift-free signal — the kernel names no discovered
|
|
503
|
-
// module KEY (the canonical id from modules/<key>/module.json). Domain terms are
|
|
504
|
-
// deliberately NOT pattern-matched: they're non-deterministic and the doorway
|
|
505
|
-
// legitimately re-exports capability accessors (getBuilderGeminiKeyRow, …); the
|
|
506
|
-
// KEY is the precise thing a generic kernel never needs to write.
|
|
507
|
-
//
|
|
508
|
-
// Scope (BV1.R70 / ADR 0091 §1): the real ~3.5k-LOC TRUST KERNEL — the module-
|
|
509
|
-
// system machinery PLUS the trust primitives + data substrate + config/identity
|
|
510
|
-
// the rest of core depends on. This replaces the original 6-file machinery-only
|
|
511
|
-
// roster (the kernel was unbounded before — the audit's finding). Deliberately
|
|
512
|
-
// EXCLUDED: the still-fused monolith remnants (src/bongos/db.js, routes/me.js,
|
|
513
|
-
// routes.js, server.js) still carry un-stranglered module seams by design
|
|
514
|
-
// (lifecycle + tranche-2 domains leave later) — scanning them would red the
|
|
515
|
-
// build on intentional state. Comment lines are skipped (a key named in a
|
|
516
|
-
// doc/example comment is documentation, not code), and the scope-map registry is
|
|
517
|
-
// exempt from the no-module-keys scan (see KERNEL_NAMES_MODULES_OK).
|
|
518
|
-
const KERNEL_FILES = [
|
|
519
|
-
// module-system machinery (the original roster)
|
|
520
|
-
'src/module-api.js', // the published doorway
|
|
521
|
-
'src/modules.js', // the registry/resolver facade
|
|
522
|
-
'src/module-seams.js', // the seam registry (ports/events/contributions)
|
|
523
|
-
'src/role-responsibilities.js', // the owner's written role statements (task 1003732) — modules.js reads it; imports nothing
|
|
524
|
-
'src/module-loader/loader.js', // the disk loader (discover → validate → mount)
|
|
525
|
-
'src/module-loader/manifest-schema.js', // the manifest validator
|
|
526
|
-
'src/module-loader/semver.js', // coreVersion compatibility
|
|
527
|
-
'src/module-loader/error-tally.js', // per-module runtime-error counts the loader feeds (task 1004637)
|
|
528
|
-
'src/bongos/module-scope-map.js', // the module→path registry (it NAMES every module — exempt below)
|
|
529
|
-
// trust primitives (ADR 0091 §1) — the authz boundary + data substrate
|
|
530
|
-
'src/bongos/auth.js', // authz gates (requireBuilder/requireRank, ADR 0016)
|
|
531
|
-
// task 1003206 (goal 1000079) split auth.js's 1,867 lines into these five sign-in
|
|
532
|
-
// flow modules. They are the SAME kernel machinery, not new domain — auth.js is a
|
|
533
|
-
// kernel file, so if they were left off this roster the boundary check would read
|
|
534
|
-
// its own carve as five kernel→non-kernel leaks. Being on the roster also means
|
|
535
|
-
// each of them is itself held to the kernel import rule, which is the point.
|
|
536
|
-
'src/bongos/auth-config.js', // provider config + OAuth scope selection
|
|
537
|
-
'src/bongos/auth-admission.js', // membership kind, admission gate, first-admin seating
|
|
538
|
-
'src/bongos/auth-github.js', // GitHub device + web OAuth flows
|
|
539
|
-
'src/bongos/auth-idp.js', // hub federation, assertion + logout-token verification
|
|
540
|
-
'src/bongos/auth-discord.js', // Discord OAuth link + guild membership
|
|
541
|
-
'src/bongos/route-rank-check.js', // deterministic route→rank classification
|
|
542
|
-
'src/bongos/permission-path-check.js', // protected-path matcher (PROTECTED_GLOBS, ADR 0043)
|
|
543
|
-
'src/bongos/goal-scope-check.js', // goal create-gate scope wall (composes the 3 matchers above; ADR 0086 §3, BV1.R60)
|
|
544
|
-
'src/bongos/secret-box.js', // AES-256-GCM per-builder secret box
|
|
545
|
-
'src/bongos/pool.js', // the singleton Postgres pool accessor
|
|
546
|
-
// task 1003208: the structured logger is kernel infrastructure in the same sense
|
|
547
|
-
// the pool is — src/module-api.js hands every module a child of it, so it sits
|
|
548
|
-
// BELOW the module boundary, not beside a domain. It imports only node built-ins
|
|
549
|
-
// and pino, so joining the roster costs nothing and buys the import-direction
|
|
550
|
-
// guarantee on the file every module now logs through.
|
|
551
|
-
'src/bongos/logger.js', // pino + request correlation + ADR 0022 redaction
|
|
552
|
-
// task 1003339 (ADR 0209): the abuse ceiling is a trust primitive in the same
|
|
553
|
-
// sense the authz gates are — authz says WHO may ask, this says HOW OFTEN, and
|
|
554
|
-
// an unauthenticated read route has nothing else holding it. src/module-api.js
|
|
555
|
-
// now hands modules the shared account-existence limiter (the onboarding
|
|
556
|
-
// module's account-existence probe spends the same budget as core's), so it
|
|
557
|
-
// sits BELOW the module boundary exactly as logger.js does. It requires NOTHING
|
|
558
|
-
// — no relative imports at all — so joining the roster costs nothing and buys
|
|
559
|
-
// the import-direction guarantee on a file two surfaces now trust.
|
|
560
|
-
'src/bongos/middleware/rate-limit.js', // the sliding-window abuse ceilings (write + per-surface read)
|
|
561
|
-
'src/bongos/db-kernel.js', // the kernel db slice — identity/audit/rank/withTx (BV1.R69)
|
|
562
|
-
// task 1002969 (ADR 0356): when an invite's door closes is part of the admission
|
|
563
|
-
// gate db-kernel.js runs, and the doorway hands the same definition to the
|
|
564
|
-
// onboarding and hub modules. It requires NOTHING, so joining costs nothing.
|
|
565
|
-
'src/bongos/invite-expiry.js', // the read-time invite expiry (INVITE_EXPIRY_DAYS + its SQL)
|
|
566
|
-
'src/bongos/routes/_helpers.js', // shared request validators the doorway re-exports
|
|
567
|
-
// config / identity (host context a module reads, never hardcodes)
|
|
568
|
-
'src/instance-config.js',
|
|
569
|
-
'src/branding.js',
|
|
570
|
-
// task 1004421 (ADR 0358): branding.js lays the chosen look over the pack through this
|
|
571
|
-
// file — the same identity/config category, requiring only instance-config and node
|
|
572
|
-
// built-ins, so it joins the roster rather than reading as a kernel→domain leak.
|
|
573
|
-
'src/hall-look.js',
|
|
574
|
-
'src/build-info.js',
|
|
575
|
-
// task 1003476 (goal 1000072): the project's stale-claim timer — host configuration
|
|
576
|
-
// a module reads rather than hardcodes, exactly the category instance-config.js and
|
|
577
|
-
// branding.js are in. The doorway (a KERNEL_FILE) re-exports it, so leaving it off
|
|
578
|
-
// this roster would read as a kernel->non-kernel leak; it imports only
|
|
579
|
-
// instance-config + node built-ins, so joining costs nothing.
|
|
580
|
-
'src/stale-timer.js',
|
|
581
|
-
// task 1003279 (goal 1000072, ADR 0232): the project's live knob store and the ROT
|
|
582
|
-
// timer resolver over it — the same category as stale-timer.js directly above (host
|
|
583
|
-
// configuration a module reads rather than hardcodes), differing only in living in
|
|
584
|
-
// the DB instead of the env, because task 1003280 requires that knob be changeable
|
|
585
|
-
// from a page without a redeploy. The doorway re-exports it, so leaving it off this
|
|
586
|
-
// roster reads as a kernel->non-kernel leak; it imports only pool.js (itself on this
|
|
587
|
-
// roster) + node built-ins, so joining costs nothing and buys the import-direction
|
|
588
|
-
// guarantee on the file every future project knob will be read through.
|
|
589
|
-
'src/bongos/project-settings.js',
|
|
590
|
-
// BV1.R86: the git-remote/slug + publish-target identity the doorway exposes
|
|
591
|
-
// (api.repoInfo) for the carved lifecycle github-push/conflict-resolve. It is
|
|
592
|
-
// KERNEL (already in the module-scope-map kernel key) and imports only the
|
|
593
|
-
// kernel (instance-config) + node built-ins, so it joins the roster cleanly.
|
|
594
|
-
'src/bongos/repo-info.js',
|
|
595
|
-
// task 1002331 (ADR 0182 D6 / ADR 0247): the project's composed join/apply door — a
|
|
596
|
-
// deterministic classifier over three policy values, the same category as
|
|
597
|
-
// route-rank-check.js and goal-scope-check.js above (a trust decision the doorway
|
|
598
|
-
// hands to modules so no module re-derives it). The doorway re-exports it, so
|
|
599
|
-
// leaving it off this roster reads as a kernel->non-kernel leak; it imports only
|
|
600
|
-
// branding.js, instance-config.js and logger.js — all on this roster — so joining
|
|
601
|
-
// costs nothing and buys the import-direction guarantee on the file that decides
|
|
602
|
-
// who may knock. (Task 1003579 moved joinabilityMode the other way: the gate reads
|
|
603
|
-
// the composed door, so reader and composer had to sit together or the two would
|
|
604
|
-
// cycle.) The ARTIST GATE joins for the same reason — task 1003575, ADR 0241.
|
|
605
|
-
'src/bongos/project-door.js', 'src/bongos/artist-gate.js',
|
|
606
|
-
// task 1004296 (ADR 0340 D5): the npm registry reader — packument, the in-process
|
|
607
|
-
// tarball stream and its small tar reader. It moved INTO the core because Settings →
|
|
608
|
-
// Software update needs it in every hall, and the doorway re-exports it
|
|
609
|
-
// (readPackageRegistry) for the module that publishes a package, so leaving it off
|
|
610
|
-
// this roster reads as a kernel->non-kernel leak. It imports only node built-ins
|
|
611
|
-
// (https, zlib), so joining costs nothing.
|
|
612
|
-
'src/bongos/package-registry.js',
|
|
613
|
-
// task 1004657 (ADR 0363 D5): requireActAlone, the gate a building's own page mounts
|
|
614
|
-
// after its permission gate — the same trust-gate category as auth.js, re-exported
|
|
615
|
-
// by the doorway, so leaving it off reads as a kernel->non-kernel leak. It imports
|
|
616
|
-
// only module-seams.js and logger.js (both on this roster) and reaches the
|
|
617
|
-
// government module through its port, never by require.
|
|
618
|
-
'src/bongos/act-alone.js',
|
|
619
|
-
];
|
|
620
|
-
|
|
621
|
-
// Kernel files exempt from the no-module-keys scan (Check 10) because naming a
|
|
622
|
-
// module is, for them, the JOB — they stay in KERNEL_FILES for the import check
|
|
623
|
-
// (Check 12), which guards dependency *direction* (a much stronger guarantee than
|
|
624
|
-
// "never write the string 'art-pipeline'"). Two legitimate reasons a kernel file names
|
|
625
|
-
// a module:
|
|
626
|
-
// • the REGISTRY — module-scope-map.js IS the module→path map (and
|
|
627
|
-
// checkScopeMapImportsProtected already guards how it derives `protected`).
|
|
628
|
-
// • the TRUST BOUNDARY — auth.js carries the Discord OAuth account-LINK flow
|
|
629
|
-
// (core by design — see modules/discord/CLAUDE.md "NOT in this module"); and
|
|
630
|
-
// permission-path-check.js / route-rank-check.js MUST name module path
|
|
631
|
-
// subtrees ('modules/grading/', …) to protect + rank-gate them. Forbidding
|
|
632
|
-
// these the string would force the trust layer to stop protecting module
|
|
633
|
-
// surfaces — exactly backwards. The generic machinery + data + config files
|
|
634
|
-
// (module-api, the loader, db-kernel, secret-box, pool, _helpers, branding,
|
|
635
|
-
// instance-config, build-info) are NOT exempt and must stay module-agnostic.
|
|
636
|
-
const KERNEL_NAMES_MODULES_OK = new Set([
|
|
637
|
-
'src/bongos/module-scope-map.js', // the module→path registry
|
|
638
|
-
// auth.js and the auth-*.js flow modules task 1003206 split out of it: the
|
|
639
|
-
// sign-in path legitimately names modules — it resolves the 'onboarding' and
|
|
640
|
-
// 'government' PORTS by key, and carries the Discord OAuth account-link flow
|
|
641
|
-
// (core by design — see modules/discord/CLAUDE.md "NOT in this module"). The
|
|
642
|
-
// exemption follows the code, exactly as the KERNEL_FILES roster above does;
|
|
643
|
-
// Check 12 still guards these files' dependency DIRECTION, which is the
|
|
644
|
-
// stronger guarantee.
|
|
645
|
-
'src/bongos/auth.js', // Discord OAuth account-link flow (core by design)
|
|
646
|
-
'src/bongos/auth-config.js',
|
|
647
|
-
'src/bongos/auth-admission.js', // resolves the 'government' rank-role port by key
|
|
648
|
-
'src/bongos/auth-github.js', // ticks the 'onboarding' port on first sign-in
|
|
649
|
-
'src/bongos/auth-idp.js', // same, on the federated path
|
|
650
|
-
'src/bongos/auth-discord.js', // the Discord account-link flow itself
|
|
651
|
-
'src/bongos/act-alone.js', // resolves the 'government' port by key for checkActAlone (task 1004657)
|
|
652
|
-
'src/bongos/permission-path-check.js', // names module path subtrees to PROTECT them
|
|
653
|
-
'src/bongos/route-rank-check.js', // names module route dirs to rank-gate them
|
|
654
|
-
'src/role-responsibilities.js', // the ideator's VERBATIM statement reads "Make good ideas" — the English word, colliding with the `ideas` key. Owner text; unparaphrasable.
|
|
655
|
-
]);
|
|
656
|
-
|
|
657
|
-
// The discovered module keys = the directory names under modules/ (a manifest's
|
|
658
|
-
// `key` must equal its dir name — manifest-schema). Empty before any move. With no explicit
|
|
659
|
-
// `modulesDir` it UNIONS every module root (core package + instance repo, ADR 0108 §Consequences
|
|
660
|
-
// #4); an explicit dir keeps the old single-dir behavior (tests). Deduped — a key resolves to
|
|
661
|
-
// exactly one root (the loader errors on a cross-root collision), and today the roots coincide.
|
|
662
|
-
function _moduleKeysIn(modulesDir) {
|
|
663
|
-
try {
|
|
664
|
-
return fs.readdirSync(modulesDir, { withFileTypes: true })
|
|
665
|
-
.filter((d) => d.isDirectory())
|
|
666
|
-
.map((d) => d.name);
|
|
667
|
-
} catch { return []; }
|
|
668
|
-
}
|
|
669
|
-
function discoveredModuleKeys(modulesDir) {
|
|
670
|
-
if (modulesDir) return _moduleKeysIn(modulesDir);
|
|
671
|
-
const keys = new Set();
|
|
672
|
-
for (const root of MODULE_ROOTS) for (const k of _moduleKeysIn(path.join(root, 'modules'))) keys.add(k);
|
|
673
|
-
return [...keys];
|
|
674
|
-
}
|
|
675
|
-
// task 1002790: two questions, previously conflated and asserted EQUAL. BROAD
|
|
676
|
-
// (every dir) stays broad — the migration checks need it, since a .sql in a
|
|
677
|
-
// manifest-less dir must still be namespace/stem-checked (schema_migrations is
|
|
678
|
-
// stem-keyed; a collision is silently SKIPPED). NARROW = carries module.json,
|
|
679
|
-
// which is what makes a module a module (ADR 0083) and what kernel-naming means.
|
|
680
|
-
function manifestModuleKeys(modulesDir) {
|
|
681
|
-
const manifested = (dir) => _moduleKeysIn(dir).filter((k) => fs.existsSync(path.join(dir, k, 'module.json')));
|
|
682
|
-
if (modulesDir) return manifested(modulesDir);
|
|
683
|
-
return [...new Set(MODULE_ROOTS.flatMap((r) => manifested(path.join(r, 'modules'))))];
|
|
684
|
-
}
|
|
685
|
-
// The DIFFERENCE as an instruction, not a bare diff — and a WARNING, because a
|
|
686
|
-
// dir without a manifest is the normal transient shape of scaffolding a module.
|
|
687
|
-
function manifestlessModuleDirs(modulesDir) {
|
|
688
|
-
const narrow = new Set(manifestModuleKeys(modulesDir));
|
|
689
|
-
return discoveredModuleKeys(modulesDir).filter((k) => !narrow.has(k)).sort().map((k) =>
|
|
690
|
-
`modules/${k}/ has no module.json — it is a directory, not a module. Add the manifest (ADR 0083) or remove the dir. Warning, not a failure: scaffolding a module dir before its manifest is normal and must not red CI.`);
|
|
691
|
-
}
|
|
692
|
-
// Absolute path to a discovered module's dir, resolving WHICH root holds it (core package or
|
|
693
|
-
// instance repo). Today both roots coincide → the single checkout.
|
|
694
|
-
function moduleDir(key) {
|
|
695
|
-
for (const root of MODULE_ROOTS) {
|
|
696
|
-
const d = path.join(root, 'modules', key);
|
|
697
|
-
if (fs.existsSync(d)) return d;
|
|
698
|
-
}
|
|
699
|
-
return path.join(CORE_ROOT, 'modules', key);
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
// Pure: scan kernel source text for any hardcoded module key, skipping comment
|
|
703
|
-
// lines. Returns violation strings (one per hit). Exported for the negative test
|
|
704
|
-
// (mirrors scanScopeMapSource / scanDeterministicBody).
|
|
705
|
-
function scanKernelForModuleKeys(text, keys) {
|
|
706
|
-
const violations = [];
|
|
707
|
-
if (!keys || keys.length === 0) return violations;
|
|
708
|
-
const probes = keys.map((k) => ({ key: k, re: keyTokenRe(k) }));
|
|
709
|
-
String(text == null ? '' : text).split('\n').forEach((raw, i) => {
|
|
710
|
-
const t = raw.trim();
|
|
711
|
-
if (!t || t.startsWith('//') || t.startsWith('*') || t.startsWith('/*')) return;
|
|
712
|
-
for (const { key, re } of probes) {
|
|
713
|
-
if (re.test(raw)) {
|
|
714
|
-
violations.push(`names module "${key}" at line ${i + 1} — the kernel/module-system machinery must stay module-agnostic; no module key may be hardcoded in core (ADR 0083 §Decision #4).`);
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
});
|
|
718
|
-
return violations;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
function checkCoreCarriesNoModuleCode() {
|
|
722
|
-
const keys = manifestModuleKeys(); // task 1002790 — NARROW: a manifest-less dir is not a module
|
|
723
|
-
const violations = [];
|
|
724
|
-
for (const relFile of KERNEL_FILES) {
|
|
725
|
-
if (KERNEL_NAMES_MODULES_OK.has(relFile)) continue; // the registry legitimately names every module
|
|
726
|
-
let text;
|
|
727
|
-
try { text = fs.readFileSync(path.join(REPO_ROOT, relFile), 'utf8'); } catch { continue; }
|
|
728
|
-
for (const v of scanKernelForModuleKeys(text, keys)) violations.push(`${relFile} ${v}`);
|
|
729
|
-
}
|
|
730
|
-
return {
|
|
731
|
-
name: 'core carries no module code',
|
|
732
|
-
ok: violations.length === 0,
|
|
733
|
-
hardFail: violations.length > 0,
|
|
734
|
-
violations,
|
|
735
|
-
warnings: manifestlessModuleDirs(), // task 1002790 — named, and never a hard fail
|
|
736
|
-
note: `kernel machinery (${KERNEL_FILES.length} files) names no module key${keys.length ? ` (keys: ${keys.join(', ')})` : ' (none yet)'} (ADR 0083 §Decision #4). A key is a modules/ dir carrying module.json; the migration checks deliberately scan every dir (task 1002790).`,
|
|
737
|
-
};
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
// ============================================================================
|
|
741
|
-
// Check 12 — the kernel imports no domain (ADR 0091 §1 / BV1.R70)
|
|
742
|
-
// ============================================================================
|
|
743
|
-
//
|
|
744
|
-
// A bounded kernel is only real if it DEPENDS on nothing but itself. This check
|
|
745
|
-
// walks every KERNEL_FILE's relative requires and flags any that reach a
|
|
746
|
-
// non-kernel core file (a soon-to-be-module domain). Kernel→kernel is fine;
|
|
747
|
-
// kernel→grandfathered-infra (the raw base pg pool, the pure path-match util) is
|
|
748
|
-
// fine; a bare npm/node spec is fine. Everything else is a tracked leak.
|
|
749
|
-
//
|
|
750
|
-
// ENFORCING (ADR 0102): the tranche-2 ratchet reached zero, so this is now a hard
|
|
751
|
-
// gate — the kernel imports only itself + grandfathered infra, and any NEW
|
|
752
|
-
// kernel→domain import fails the build (violations). The last leaks cleared were
|
|
753
|
-
// auth.js→db (carved to db-kernel), the doorway's Gemini-key re-exports (→ the
|
|
754
|
-
// art-pipeline 'art.getBuilderGeminiKeyRow' port) and builderRollingAvgGrade (→ the
|
|
755
|
-
// grading 'grade.builderRollingAvgGrade' port), plus reclassifying llm-cache /
|
|
756
|
-
// llm-pricing as kernel-adjacent infra. Adding a leak back reds the build.
|
|
757
|
-
|
|
758
|
-
// Grandfathered kernel-adjacent targets a KERNEL_FILE may import without it
|
|
759
|
-
// counting as a domain leak. The still-fused src/bongos/db.js monolith is NOT here:
|
|
760
|
-
// a kernel file reaching into it IS a real (tracked) leak until the identity/
|
|
761
|
-
// session slices finish carving into db-kernel.js.
|
|
762
|
-
const KERNEL_IMPORT_ALLOWLIST = new Set([
|
|
763
|
-
'src/db.js', // the raw shared pg Pool (base infra; pool.js wraps it)
|
|
764
|
-
'src/bongos/path-match.js', // pure touches-overlap matcher (no domain logic)
|
|
765
|
-
// Cross-cutting LLM-cost infra (ADR 0102): a stateless token→USD pricing table
|
|
766
|
-
// (llm-pricing) + a best-effort content-addressed cache (llm-cache), consumed by
|
|
767
|
-
// core, the grading module, and the CLI cost tooling ALIKE — no domain logic and
|
|
768
|
-
// no domain state beyond a cache table. Same category as the pg pool / path-match,
|
|
769
|
-
// not a domain module core would have to depend on anyway. The doorway may import
|
|
770
|
-
// them; they never flip the kernel→domain leak.
|
|
771
|
-
'src/bongos/llm-cache.js',
|
|
772
|
-
'src/bongos/llm-pricing.js',
|
|
773
|
-
// The cheapest-model-first cascade router (task 1001691 / ADR 0101 Part 1):
|
|
774
|
-
// a pure ladder + an INJECTED runner (never a domain call itself — its own
|
|
775
|
-
// header says so: "nothing calls it but its mock unit test" until this
|
|
776
|
-
// task), holding no domain state of its own. Its first real caller is the
|
|
777
|
-
// lifecycle module's relevance judge, which reaches it through the doorway
|
|
778
|
-
// exactly as grading reaches llm-cache — same category as the pg pool /
|
|
779
|
-
// path-match / llm-cache above, not a domain module core would otherwise
|
|
780
|
-
// depend on.
|
|
781
|
-
'src/bongos/cascade-dispatch.js',
|
|
782
|
-
]);
|
|
783
|
-
|
|
784
|
-
// Pure: for relative require `spec` from kernel file `fromRel` (repo-relative),
|
|
785
|
-
// return the offending non-kernel target relpath, or null if the import is clean
|
|
786
|
-
// (kernel→kernel, kernel→allowlisted-infra, or a bare npm/node spec). Exported
|
|
787
|
-
// for the "actually catches a leak" negative test (mirrors scanScopeMapSource).
|
|
788
|
-
function kernelDomainImport(fromRel, spec, kernelSet = new Set(KERNEL_FILES), allow = KERNEL_IMPORT_ALLOWLIST) {
|
|
789
|
-
if (!/^\.\.?\//.test(spec)) return null; // bare npm/node spec — not our concern
|
|
790
|
-
const absTarget = path.resolve(path.dirname(path.join(REPO_ROOT, fromRel)), spec);
|
|
791
|
-
const r = rel(absTarget);
|
|
792
|
-
const forms = [r, r + '.js', r.replace(/\/$/, '') + '/index.js'];
|
|
793
|
-
if (forms.some((f) => kernelSet.has(f))) return null; // kernel → kernel
|
|
794
|
-
if (forms.some((f) => allow.has(f))) return null; // grandfathered infra/util
|
|
795
|
-
if (!/^src\//.test(r)) return null; // only flag app-source targets
|
|
796
|
-
return r.endsWith('.js') || r.endsWith('.json') ? r : `${r}.js`; // name the real file
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
function checkKernelImportsNoDomain() {
|
|
800
|
-
const kernelSet = new Set(KERNEL_FILES);
|
|
801
|
-
const findings = [];
|
|
802
|
-
for (const relFile of KERNEL_FILES) {
|
|
803
|
-
let text;
|
|
804
|
-
try { text = fs.readFileSync(path.join(REPO_ROOT, relFile), 'utf8'); } catch { continue; }
|
|
805
|
-
for (const raw of text.split('\n')) {
|
|
806
|
-
const t = raw.trim();
|
|
807
|
-
if (t.startsWith('//') || t.startsWith('*') || t.startsWith('/*')) continue;
|
|
808
|
-
let m; REQUIRE_RE.lastIndex = 0;
|
|
809
|
-
while ((m = REQUIRE_RE.exec(raw))) {
|
|
810
|
-
const target = kernelDomainImport(relFile, m[1], kernelSet);
|
|
811
|
-
if (target) findings.push(`${relFile} → require('${m[1]}') reaches non-kernel core file ${target} — a kernel file must depend only on the kernel (ADR 0091 §1). Carve ${target}'s domain out (or promote it into the kernel) to clear this.`);
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
return {
|
|
816
|
-
name: 'kernel imports no domain',
|
|
817
|
-
ok: findings.length === 0,
|
|
818
|
-
hardFail: findings.length > 0, // ENFORCING (ADR 0102): the ratchet reached zero — any new kernel→domain import now reds the build
|
|
819
|
-
violations: findings,
|
|
820
|
-
warnings: [],
|
|
821
|
-
note: `every KERNEL_FILE (${KERNEL_FILES.length}) must import only the kernel + grandfathered infra — ENFORCING (ADR 0091 §1 / ADR 0102).${findings.length ? ` ${findings.length} leak(s).` : ' Boundary clean.'}`,
|
|
822
|
-
};
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
// ============================================================================
|
|
826
|
-
// Check 11 — module migrations are additive + namespaced (ADR 0083 §Decision #5 / design 04§3)
|
|
827
|
-
// ============================================================================
|
|
828
|
-
//
|
|
829
|
-
// A module owns its DB slice through migrations under modules/<key>/migrations/.
|
|
830
|
-
// Two invariants keep that slice from clobbering core or a sibling:
|
|
831
|
-
// • ADDITIVE — no destructive DDL. "Disable a module" means "stop applying its
|
|
832
|
-
// migrations," never "drop its tables" (ADR 0083 §Module-owned migrations);
|
|
833
|
-
// there is no down path, so a DROP/TRUNCATE can only be an accident.
|
|
834
|
-
// • NAMESPACED — every object it CREATEs lives under the <key>_ prefix
|
|
835
|
-
// (art-pipeline → art_pipeline_), and it may only ALTER its own namespaced tables;
|
|
836
|
-
// core/sibling state is reached through the doorway/seams, never raw DDL.
|
|
837
|
-
//
|
|
838
|
-
// LEGACY_NAMESPACED: tables that predate the <key>_-prefix convention (created before the module
|
|
839
|
-
// system existed). Grandfathered per-module to avoid requiring a rename migration for legacy prod
|
|
840
|
-
// data. The fitness rule applies in full to any NEW migration a module ships.
|
|
841
|
-
const LEGACY_NAMESPACED = {
|
|
842
|
-
// game module: world_events + players were created before the module system (V1 schema). The
|
|
843
|
-
// schema_migrations table is a core tracking table that every migration may re-create idempotently.
|
|
844
|
-
game: new Set(['world_events', 'players', 'schema_migrations']),
|
|
845
|
-
// government module: the module KEY was renamed governance→government (ADR 0174, goal 1000068),
|
|
846
|
-
// so its own historical migrations now read as "outside the namespace" purely because the key
|
|
847
|
-
// moved underneath them. These three tables ARE this module's — under the name it used to have.
|
|
848
|
-
// They are not renamed in place because schema_migrations is keyed by filename STEM: renaming an
|
|
849
|
-
// already-applied migration file makes it look unapplied and re-runs it, and governance_002 is a
|
|
850
|
-
// seed/backfill. government_001_rename_from_governance.sql renames the live tables forward; these
|
|
851
|
-
// entries let the historical files that created them keep describing what actually happened.
|
|
852
|
-
government: new Set([
|
|
853
|
-
'governance_roles', 'governance_builder_roles', 'governance_role_permissions',
|
|
854
|
-
]),
|
|
855
|
-
};
|
|
856
|
-
const DESTRUCTIVE_DDL = [
|
|
857
|
-
{ re: /\bdrop\s+table\b/i, label: 'DROP TABLE' },
|
|
858
|
-
{ re: /\balter\s+table\b[\s\S]*?\bdrop\s+(?:column|constraint)\b/i, label: 'ALTER TABLE … DROP COLUMN/CONSTRAINT' },
|
|
859
|
-
{ re: /\bdrop\s+(?:column|constraint)\b/i, label: 'DROP COLUMN/CONSTRAINT' },
|
|
860
|
-
{ re: /\bdrop\s+(?:index|type|view|sequence|schema|materialized\s+view)\b/i, label: 'DROP <object>' },
|
|
861
|
-
{ re: /\btruncate\b/i, label: 'TRUNCATE' },
|
|
862
|
-
];
|
|
863
|
-
const CREATE_OBJ_RE = /\bcreate\s+(?:or\s+replace\s+)?(?:unique\s+)?(?:materialized\s+)?(table|view|sequence|type)\s+(?:if\s+not\s+exists\s+)?("?[\w.]+"?)/gi;
|
|
864
|
-
const CREATE_INDEX_RE = /\bcreate\s+(?:unique\s+)?index\s+(?:concurrently\s+)?(?:if\s+not\s+exists\s+)?(?:"?[\w.]+"?)\s+on\s+(?:only\s+)?("?[\w.]+"?)/gi;
|
|
865
|
-
const ALTER_TABLE_RE = /\balter\s+table\s+(?:if\s+exists\s+)?(?:only\s+)?("?[\w.]+"?)/gi;
|
|
866
|
-
|
|
867
|
-
// SQL object-namespace prefix for a module key: art-pipeline → art_pipeline (SQL-safe).
|
|
868
|
-
function moduleNamespace(key) { return key.replace(/-/g, '_'); }
|
|
869
|
-
|
|
870
|
-
// strip SQL comments so a commented-out statement is never scanned
|
|
871
|
-
function stripSqlComments(sql) {
|
|
872
|
-
return String(sql == null ? '' : sql)
|
|
873
|
-
.replace(/\/\*[\s\S]*?\*\//g, ' ')
|
|
874
|
-
.replace(/--[^\n]*/g, ' ');
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
// is `rawName` (possibly quoted / schema-qualified) under the <ns>_ namespace?
|
|
878
|
-
function inNamespace(rawName, ns, legacySet) {
|
|
879
|
-
const name = String(rawName).replace(/"/g, '').replace(/^[A-Za-z_]\w*\./, '');
|
|
880
|
-
return name.startsWith(ns + '_') || (legacySet && legacySet.has(name));
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
// A CHECK-enum WIDENING is additive-in-spirit: `DROP CONSTRAINT IF EXISTS <c>` PAIRED
|
|
884
|
-
// with a re-`ADD CONSTRAINT <c>` (SAME name) in the SAME migration only PERMITS more
|
|
885
|
-
// values — no existing row changes, no data is lost (task 1978: provisioning gains a
|
|
886
|
-
// 'standalone' hosting_shape). Allow that exact pattern; a BARE `DROP CONSTRAINT` (no
|
|
887
|
-
// re-add), or any DROP TABLE/COLUMN/TRUNCATE, stays destructive. PURE.
|
|
888
|
-
function reAddedConstraintNames(sql) {
|
|
889
|
-
const names = new Set();
|
|
890
|
-
const re = /\badd\s+constraint\s+("?[\w.]+"?)/gi;
|
|
891
|
-
let m;
|
|
892
|
-
while ((m = re.exec(sql))) names.add(m[1].replace(/"/g, ''));
|
|
893
|
-
return names;
|
|
894
|
-
}
|
|
895
|
-
function isConstraintWidening(stmt, reAdded) {
|
|
896
|
-
const m = /\bdrop\s+constraint\s+(?:if\s+exists\s+)?("?[\w.]+"?)/i.exec(stmt);
|
|
897
|
-
if (!m) return false; // not a DROP CONSTRAINT at all
|
|
898
|
-
// never let a DROP CONSTRAINT statement smuggle a table/column drop past the gate
|
|
899
|
-
if (/\bdrop\s+(?:table|column|index|type|view|sequence|schema|materialized\s+view)\b/i.test(stmt)) return false;
|
|
900
|
-
if (/\btruncate\b/i.test(stmt)) return false;
|
|
901
|
-
return reAdded.has(m[1].replace(/"/g, '')); // re-added same-named constraint → widening
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
// The ONE destructive shape a module may carry: an ACKNOWLEDGED contract-phase
|
|
905
|
-
// `ALTER TABLE <own table> DROP COLUMN <c>` (task 1003092 — the expand-then-contract
|
|
906
|
-
// rename of ADR 0177 has to finish; ADR 0083 §Module-owned migrations, amended). The
|
|
907
|
-
// pragma is read off the RAW sql (it is a comment); everything else here still runs.
|
|
908
|
-
const { acknowledgedContraction, isAcknowledgedColumnContraction } = require('./fitness-migration-contraction.js');
|
|
909
|
-
|
|
910
|
-
// Pure: violations for ONE module's migration SQL. Exported for the negative test.
|
|
911
|
-
function moduleMigrationViolations(key, sql) {
|
|
912
|
-
const ns = moduleNamespace(key);
|
|
913
|
-
const legacy = LEGACY_NAMESPACED[key] || null;
|
|
914
|
-
const clean = stripSqlComments(sql);
|
|
915
|
-
const violations = [];
|
|
916
|
-
// additive — scan per statement so an ALTER…DROP never spans a `;`
|
|
917
|
-
const reAdded = reAddedConstraintNames(clean);
|
|
918
|
-
const acknowledged = acknowledgedContraction(sql);
|
|
919
|
-
const ownTable = (t) => inNamespace(t, ns, legacy);
|
|
920
|
-
for (const stmt of clean.split(';')) {
|
|
921
|
-
if (isConstraintWidening(stmt, reAdded)) continue; // additive CHECK-enum widening (task 1978)
|
|
922
|
-
if (isAcknowledgedColumnContraction(stmt, { acknowledged, inNamespace: ownTable })) continue; // contract phase (task 1003092)
|
|
923
|
-
for (const d of DESTRUCTIVE_DDL) {
|
|
924
|
-
if (d.re.test(stmt)) {
|
|
925
|
-
violations.push(`module "${key}" migration uses destructive DDL (${d.label}) — module migrations must be ADDITIVE; disabling a module stops applying, it never drops (ADR 0083 §Decision #5).`);
|
|
926
|
-
break; // one destructive flag per statement is enough
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
// namespaced — CREATEd objects + ALTER targets must live under <ns>_ (or be grandfathered)
|
|
931
|
-
let m;
|
|
932
|
-
CREATE_OBJ_RE.lastIndex = 0;
|
|
933
|
-
while ((m = CREATE_OBJ_RE.exec(clean))) {
|
|
934
|
-
if (!inNamespace(m[2], ns, legacy)) {
|
|
935
|
-
violations.push(`module "${key}" migration creates ${m[1].toUpperCase()} ${m[2]} outside its namespace — module objects must be ${ns}_-prefixed (ADR 0083 §Decision #5).`);
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
CREATE_INDEX_RE.lastIndex = 0;
|
|
939
|
-
while ((m = CREATE_INDEX_RE.exec(clean))) {
|
|
940
|
-
if (!inNamespace(m[1], ns, legacy)) {
|
|
941
|
-
violations.push(`module "${key}" migration indexes a non-namespaced table ${m[1]} — a module migration may only touch its own ${ns}_ tables (ADR 0083 §Decision #5).`);
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
ALTER_TABLE_RE.lastIndex = 0;
|
|
945
|
-
while ((m = ALTER_TABLE_RE.exec(clean))) {
|
|
946
|
-
if (!inNamespace(m[1], ns, legacy)) {
|
|
947
|
-
violations.push(`module "${key}" migration alters a non-namespaced table ${m[1]} — a module migration may only touch its own ${ns}_ tables; reach core state through the doorway/seams, not DDL (ADR 0083 §Decision #5).`);
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
return violations;
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
function checkModuleMigrationsAdditive() {
|
|
954
|
-
const violations = [];
|
|
955
|
-
let scanned = 0;
|
|
956
|
-
for (const key of discoveredModuleKeys()) { // union across module roots (ADR 0108 §Consequences #4)
|
|
957
|
-
const migDir = path.join(moduleDir(key), 'migrations');
|
|
958
|
-
let files = [];
|
|
959
|
-
try { files = fs.readdirSync(migDir).filter((f) => f.endsWith('.sql')); } catch { continue; }
|
|
960
|
-
for (const f of files.sort()) {
|
|
961
|
-
scanned += 1;
|
|
962
|
-
const sql = fs.readFileSync(path.join(migDir, f), 'utf8');
|
|
963
|
-
for (const v of moduleMigrationViolations(key, sql)) {
|
|
964
|
-
violations.push(`modules/${key}/migrations/${f}: ${v}`);
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
return {
|
|
969
|
-
name: 'module migrations additive + namespaced',
|
|
970
|
-
ok: violations.length === 0,
|
|
971
|
-
hardFail: violations.length > 0,
|
|
972
|
-
violations,
|
|
973
|
-
warnings: [],
|
|
974
|
-
note: `${scanned} module migration file(s): additive (no destructive DDL) + <key>_-namespaced objects (ADR 0083 §Decision #5).`,
|
|
975
|
-
};
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
// ============================================================================
|
|
979
|
-
// Check 11b — migration FILENAMES are namespaced + no cross-root stem collision
|
|
980
|
-
// (ADR 0108 §5; extends Check 11 to the cross-repo layer)
|
|
981
|
-
// ============================================================================
|
|
982
|
-
//
|
|
983
|
-
// Check 11 (above) guards a module migration's OBJECTS (additive + <key>_-namespaced
|
|
984
|
-
// tables). THIS check guards migration FILENAMES across all three roots — the
|
|
985
|
-
// discipline that lets the core repo and the instance repo version independently
|
|
986
|
-
// (ADR 0108) without their migrations colliding:
|
|
987
|
-
// • migrations/*.sql (CORE) → NEW files must be core_-prefixed
|
|
988
|
-
// • migrations/instance/*.sql (INSTANCE) → stay bare (or instance_-prefixed)
|
|
989
|
-
// • modules/<key>/migrations/ (MODULE) → NEW files must be <key>_-prefixed
|
|
990
|
-
// Existing bare files are grandfathered (migration-namespace.js LEGACY_BARE_*). The
|
|
991
|
-
// second invariant is the real bug guard: migrate.sh keys schema_migrations by
|
|
992
|
-
// filename STEM, so two migrations from different sources sharing a stem would apply
|
|
993
|
-
// ONCE and the other be SILENTLY SKIPPED (never applied). Single-root today; W6/task
|
|
994
|
-
// 1886 makes the root resolution two-root-aware once the core installs from node_modules.
|
|
995
|
-
function sqlFilesIn(absDir) {
|
|
996
|
-
try { return fs.readdirSync(absDir).filter((f) => f.endsWith('.sql')).sort(); }
|
|
997
|
-
catch { return []; } // dir absent (e.g. no migrations/instance in a vanilla instance) → nothing to scan
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
function checkMigrationNamespacing() {
|
|
1001
|
-
const violations = [];
|
|
1002
|
-
const files = []; // { source, moduleKey?, basename } — fed to the stem-collision scan
|
|
1003
|
-
|
|
1004
|
-
const coreFiles = sqlFilesIn(path.join(CORE_ROOT, 'migrations')); // core migrations ship in the core package
|
|
1005
|
-
for (const f of coreFiles) {
|
|
1006
|
-
const v = filenameViolation(CORE_NS, f);
|
|
1007
|
-
if (v) violations.push(`migrations/${f}: ${v}`);
|
|
1008
|
-
files.push({ source: CORE_NS, basename: f });
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
const instFiles = sqlFilesIn(path.join(INSTANCE_ROOT, 'migrations', 'instance')); // instance seeds live in the host repo
|
|
1012
|
-
for (const f of instFiles) {
|
|
1013
|
-
const v = filenameViolation(INSTANCE_NS, f);
|
|
1014
|
-
if (v) violations.push(`migrations/instance/${f}: ${v}`);
|
|
1015
|
-
files.push({ source: INSTANCE_NS, basename: f });
|
|
1016
|
-
}
|
|
1017
|
-
|
|
1018
|
-
let moduleCount = 0;
|
|
1019
|
-
for (const key of discoveredModuleKeys()) {
|
|
1020
|
-
for (const f of sqlFilesIn(path.join(moduleDir(key), 'migrations'))) {
|
|
1021
|
-
moduleCount += 1;
|
|
1022
|
-
const v = filenameViolation('module', f, { moduleKey: key });
|
|
1023
|
-
if (v) violations.push(`modules/${key}/migrations/${f}: ${v}`);
|
|
1024
|
-
files.push({ source: 'module', moduleKey: key, basename: f });
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
for (const c of stemCollisions(files)) {
|
|
1029
|
-
violations.push(`migration stem "${c.stem}" is produced by more than one source (${c.files.join(', ')}) — schema_migrations is stem-keyed, so one applies and the rest are SILENTLY SKIPPED; namespace them (ADR 0108 §5).`);
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
// Two DIFFERENT stems at one number inside ONE series (task 1003646). Not the
|
|
1033
|
-
// silent-skip above — all of them apply — but migrate.sh orders by basename, so
|
|
1034
|
-
// their relative order is the alphabetical accident of the slug, and a from-scratch
|
|
1035
|
-
// replay can order them differently from the merge order prod applied. Renumbering an
|
|
1036
|
-
// APPLIED migration re-runs it, so the fix for a new one is to renumber BEFORE it
|
|
1037
|
-
// lands; the single pre-existing case is grandfathered in migration-namespace.js.
|
|
1038
|
-
for (const c of numberCollisions(files)) {
|
|
1039
|
-
violations.push(`migration number ${String(c.number).padStart(3, '0')} is used by ${c.files.length} different migrations in one series (${c.series}): ${c.files.join(', ')} — each was allocated max+1 from its own branch point. migrate.sh applies in BASENAME order, so their order is decided by the slug alphabetically and a fresh replay can differ from the order prod applied. Renumber the one that has NOT landed yet (renaming an applied migration re-runs it) (task 1003646).`);
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
return {
|
|
1043
|
-
name: 'migration filenames namespaced + no stem/number collision (ADR 0108 §5)',
|
|
1044
|
-
ok: violations.length === 0,
|
|
1045
|
-
hardFail: violations.length > 0,
|
|
1046
|
-
violations,
|
|
1047
|
-
warnings: [],
|
|
1048
|
-
note: `${coreFiles.length} core + ${instFiles.length} instance + ${moduleCount} module migration file(s): new core→core_, new module→<key>_, instance bare; no cross-root stem collision, and no two migrations share a number within one series.`,
|
|
1049
|
-
};
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
// ============================================================================
|
|
1053
|
-
// Check — hall sections are registry-owned, not hardcoded (BV1.R75 / ADR 0062 §4)
|
|
1054
|
-
// ============================================================================
|
|
1055
|
-
// The builders'-hall widgets are now a REGISTRY (modules/hall-ui/public/dom-utils.js
|
|
1056
|
-
// contributeHallWidget; the core set in modules/hall-ui/public/hall-widgets.js, modules
|
|
1057
|
-
// via their own client script). The hall's <main> is filled by builders.js from that
|
|
1058
|
-
// registry. So no widget may be hardcoded as a literal <section class="scroll"> inside
|
|
1059
|
-
// <main> in index.html — that was the pre-R75 second copy this carve removed. This
|
|
1060
|
-
// gate fails if one creeps back, keeping the registry the single source of truth (so a
|
|
1061
|
-
// reskin/module-toggle reaches every widget). Self-contained: a pure scan of
|
|
1062
|
-
// index.html's <main>, no module/registry state needed. Exported for the unit test.
|
|
1063
|
-
// (The hall surface itself carved to modules/hall-ui/public/ in BV1.R85.)
|
|
1064
|
-
//
|
|
1065
|
-
// task 2177 — the check also asserts the HOME ZONE BUDGETS. builders.js caps how
|
|
1066
|
-
// many widgets each Home zone mounts (ZONE_BUDGETS); past the cap a widget still
|
|
1067
|
-
// mounts, but into a hidden overflow behind a "More" link. That graceful degrade
|
|
1068
|
-
// is the runtime safety net — it is NOT a licence to keep adding cards, and
|
|
1069
|
-
// because nothing goes red, a Home that has quietly outgrown its budget looks
|
|
1070
|
-
// fine. So CI counts the registrations statically and fails on a breach: the
|
|
1071
|
-
// budget becomes a decision someone has to make deliberately (raise the number
|
|
1072
|
-
// in builders.js, with a reason) instead of one that erodes.
|
|
1073
|
-
//
|
|
1074
|
-
// NOT statically checkable, by design: the `home-banner` rule is "at most ONE
|
|
1075
|
-
// VISIBLE", not "at most one registered" — both banner widgets (welcome,
|
|
1076
|
-
// getting-started) are hiddenByDefault and reveal themselves from onboarding
|
|
1077
|
-
// state, so only runtime knows the count. It is documented as a runtime
|
|
1078
|
-
// invariant in modules/hall-ui/CLAUDE.md rather than faked with a static count
|
|
1079
|
-
// that would either fail today or assert nothing.
|
|
1080
|
-
const HALL_INDEX = path.join(moduleDir('hall-ui'), 'public', 'index.html'); // hall-ui is a module — resolve its root (ADR 0108)
|
|
1081
|
-
const HALL_PUBLIC = path.join(moduleDir('hall-ui'), 'public');
|
|
1082
|
-
// task 1003206 split the hall page script: builders.js keeps state/loading/wiring
|
|
1083
|
-
// and hall-render.js holds the view painters — ZONE_BUDGETS travelled with the
|
|
1084
|
-
// widget mounting. Read whichever of the pair actually declares it, so this
|
|
1085
|
-
// check follows the code instead of a filename (it went vacuous on the move).
|
|
1086
|
-
const HALL_BUILDERS_JS = path.join(HALL_PUBLIC, 'builders.js');
|
|
1087
|
-
const HALL_RENDER_JS = path.join(HALL_PUBLIC, 'hall-render.js');
|
|
1088
|
-
function hallWidgetSource() {
|
|
1089
|
-
const parts = [];
|
|
1090
|
-
for (const f of [HALL_BUILDERS_JS, HALL_RENDER_JS]) {
|
|
1091
|
-
try { parts.push(fs.readFileSync(f, 'utf8')); } catch { /* absent → skip */ }
|
|
1092
|
-
}
|
|
1093
|
-
return parts.join('\n');
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
// Parse builders.js's ZONE_BUDGETS object literal — the single source of truth
|
|
1097
|
-
// for the caps (this check must never carry its own copy of the numbers).
|
|
1098
|
-
function parseZoneBudgets(js) {
|
|
1099
|
-
const block = js.match(/const\s+ZONE_BUDGETS\s*=\s*\{([^}]*)\}/);
|
|
1100
|
-
if (!block) return null;
|
|
1101
|
-
const budgets = {};
|
|
1102
|
-
for (const [, zone, n] of block[1].matchAll(/['"]([\w-]+)['"]\s*:\s*(\d+)/g)) {
|
|
1103
|
-
budgets[zone] = Number(n);
|
|
1104
|
-
}
|
|
1105
|
-
return Object.keys(budgets).length ? budgets : null;
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
// Count registrations per Home zone across every hall client script that calls
|
|
1109
|
-
// contributeHallWidget. The zones are static string literals in the registration
|
|
1110
|
-
// object, so a literal scan is exact for the code we have (and a computed zone
|
|
1111
|
-
// would be a placement smell in its own right — dom-utils' runtime validation
|
|
1112
|
-
// still rejects an unknown one). Requiring the contributeHallWidget mention is
|
|
1113
|
-
// what keeps an unrelated `zone:` key in some other object from eating budget.
|
|
1114
|
-
function scanHallZoneCounts(dir = HALL_PUBLIC, fsImpl = fs) {
|
|
1115
|
-
const counts = {};
|
|
1116
|
-
let files = [];
|
|
1117
|
-
try { files = fsImpl.readdirSync(dir).filter((f) => f.endsWith('.js')); } catch { return counts; }
|
|
1118
|
-
for (const file of files) {
|
|
1119
|
-
let src = '';
|
|
1120
|
-
try { src = fsImpl.readFileSync(path.join(dir, file), 'utf8'); } catch { continue; }
|
|
1121
|
-
if (!src.includes('contributeHallWidget')) continue;
|
|
1122
|
-
for (const [, zone] of src.matchAll(/\bzone:\s*['"]([\w-]+)['"]/g)) {
|
|
1123
|
-
counts[zone] = (counts[zone] || 0) + 1;
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
return counts;
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
function checkHallZoneBudgets(fsImpl = fs) {
|
|
1130
|
-
let js = '';
|
|
1131
|
-
try {
|
|
1132
|
-
js = [HALL_BUILDERS_JS, HALL_RENDER_JS]
|
|
1133
|
-
.map((f) => { try { return fsImpl.readFileSync(f, 'utf8'); } catch { return ''; } })
|
|
1134
|
-
.join('\n');
|
|
1135
|
-
} catch { return []; }
|
|
1136
|
-
const budgets = parseZoneBudgets(js);
|
|
1137
|
-
if (!budgets) {
|
|
1138
|
-
return ['modules/hall-ui/public/{builders,hall-render}.js no longer declares a parseable ZONE_BUDGETS literal — the Home zone budgets are unenforced (task 2177).'];
|
|
1139
|
-
}
|
|
1140
|
-
const counts = scanHallZoneCounts(HALL_PUBLIC, fsImpl);
|
|
1141
|
-
const violations = [];
|
|
1142
|
-
for (const [zone, budget] of Object.entries(budgets)) {
|
|
1143
|
-
const n = counts[zone] || 0;
|
|
1144
|
-
if (n > budget) {
|
|
1145
|
-
violations.push(
|
|
1146
|
-
`Home zone "${zone}" has ${n} registered hall widgets but its budget is ${budget} — the extras mount into the hidden overflow, so Home silently grew. Move it to its own page (see modules/hall-ui/CLAUDE.md §Placement), or raise ZONE_BUDGETS['${zone}'] in modules/hall-ui/public/builders.js deliberately (task 2177).`);
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1149
|
-
return violations;
|
|
1150
|
-
}
|
|
1151
|
-
|
|
1152
|
-
function hallMainSlice(html) {
|
|
1153
|
-
// Strip HTML comments first so a comment that merely MENTIONS <main> or a
|
|
1154
|
-
// <section class="scroll"> (e.g. the carve's own explanatory note) never trips
|
|
1155
|
-
// the scan — only real, rendered markup counts.
|
|
1156
|
-
const stripped = html.replace(/<!--[\s\S]*?-->/g, '');
|
|
1157
|
-
const open = stripped.indexOf('<main');
|
|
1158
|
-
if (open === -1) return '';
|
|
1159
|
-
const start = stripped.indexOf('>', open);
|
|
1160
|
-
const close = stripped.indexOf('</main>', start === -1 ? open : start);
|
|
1161
|
-
if (start === -1 || close === -1) return '';
|
|
1162
|
-
return stripped.slice(start + 1, close);
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
function scanHallSectionRegistry(html) {
|
|
1166
|
-
const main = hallMainSlice(html);
|
|
1167
|
-
// A hall widget section carries class="scroll" (possibly with modifiers, e.g.
|
|
1168
|
-
// "scroll scroll--welcome"). Catch any <section ... class="...scroll..."> in <main>.
|
|
1169
|
-
const re = /<section\b[^>]*\bclass\s*=\s*"(?:[^"]*\b)?scroll\b[^"]*"/gi;
|
|
1170
|
-
const hits = main.match(re) || [];
|
|
1171
|
-
return hits.map((h) => h.replace(/\s+/g, ' ').trim());
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
|
-
function checkHallSectionRegistry() {
|
|
1175
|
-
let html = '';
|
|
1176
|
-
try { html = fs.readFileSync(HALL_INDEX, 'utf8'); }
|
|
1177
|
-
catch { return { name: 'hall widgets are registry-owned (ADR 0062 §4)', ok: true, hardFail: false, violations: [], warnings: ['modules/hall-ui/public/index.html not found — skipped'], note: 'index.html absent.' }; }
|
|
1178
|
-
const hardcoded = scanHallSectionRegistry(html);
|
|
1179
|
-
const violations = hardcoded.map((s) =>
|
|
1180
|
-
`modules/hall-ui/public/index.html <main> hardcodes a hall section "${s}" — register it via window.OTB.contributeHallWidget (modules/hall-ui/public/hall-widgets.js for core, a module's client script otherwise), don't inline the markup (BV1.R75 / ADR 0062 §4).`);
|
|
1181
|
-
violations.push(...checkHallZoneBudgets());
|
|
1182
|
-
return {
|
|
1183
|
-
name: 'hall widgets are registry-owned + within zone budget (ADR 0062 §4, task 2177)',
|
|
1184
|
-
ok: violations.length === 0,
|
|
1185
|
-
hardFail: violations.length > 0,
|
|
1186
|
-
violations,
|
|
1187
|
-
warnings: [],
|
|
1188
|
-
note: 'modules/hall-ui/public/index.html <main> contains no hardcoded <section class="scroll">, and every Home zone is within the ZONE_BUDGETS cap builders.js declares — the registry is the single source of truth and Home cannot grow unnoticed.',
|
|
1189
|
-
};
|
|
1190
|
-
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
// ============================================================================
|
|
1194
|
-
// Check 2c — every SKILL.md frontmatter parses the way Claude Code's YAML reader reads it (task 1003548)
|
|
1195
|
-
// ============================================================================
|
|
1196
|
-
// Ten of fifty skills shipped with an unquoted description holding ": " or " #": YAML dropped or
|
|
1197
|
-
// truncated EVERY field, the skill matched on its body text, and nothing in CI noticed. A parse
|
|
1198
|
-
// error is a hard fail; description length and the listing budget are advisory (the listing is
|
|
1199
|
-
// resident in every session, ~1% of context, and gets truncated past ~8k chars). The check reads
|
|
1200
|
-
// every skill Claude Code can load — the instance's .claude/skills/ AND the module-owned
|
|
1201
|
-
// modules/*/skills/ that claude-materialize.js copies into it (task 1003587: scanning only the
|
|
1202
|
-
// tracked root meant 14 ui-design skills went unlinted until the untracked copy existed, so four
|
|
1203
|
-
// unparseable frontmatters shipped and fitness only went red on a checkout that had materialized).
|
|
1204
|
-
// A quiet pass when a checkout carries none (published core).
|
|
1205
|
-
function checkSkillFrontmatter() {
|
|
1206
|
-
const violations = [];
|
|
1207
|
-
const warnings = [];
|
|
1208
|
-
let lint;
|
|
1209
|
-
try { lint = require('./skill-lint'); } catch (e) {
|
|
1210
|
-
return { name: 'skill frontmatter parses (task 1003548)', ok: true, hardFail: false, violations, warnings: [`skill-lint unavailable: ${e.message}`], note: 'linter missing — check skipped.' };
|
|
1211
|
-
}
|
|
1212
|
-
const files = lint.listSkillFiles(INSTANCE_ROOT);
|
|
1213
|
-
// Lint every file; count the listing over the skills RESIDENT here (task 1004470).
|
|
1214
|
-
const report = lint.lintSkills(files, { resident: lint.residentSkillFiles(INSTANCE_ROOT, { files }) });
|
|
1215
|
-
const rel = (f) => path.relative(INSTANCE_ROOT, f).replace(/\\/g, '/');
|
|
1216
|
-
const long = [];
|
|
1217
|
-
for (const r of report.results) {
|
|
1218
|
-
for (const e of r.errors) violations.push(`${rel(r.file)}: ${e}`);
|
|
1219
|
-
if (r.description.length > lint.DESC_WARN_CHARS) long.push({ file: rel(r.file), n: r.description.length });
|
|
1220
|
-
}
|
|
1221
|
-
if (long.length) {
|
|
1222
|
-
long.sort((a, b) => b.n - a.n);
|
|
1223
|
-
// The skill's own name is its PARENT dir — a fixed path index would read "skills"
|
|
1224
|
-
// for a module-owned path (modules/<key>/skills/<name>/SKILL.md).
|
|
1225
|
-
const skillName = (f) => f.split('/').slice(-2, -1)[0] || f;
|
|
1226
|
-
warnings.push(`${long.length} description(s) over ${lint.DESC_WARN_CHARS} chars (longest: ${long.slice(0, 4).map((l) => `${skillName(l.file)} ${l.n}`).join(', ')}) — every char is resident in every session; run node scripts/gds/skill-lint.js.`);
|
|
1227
|
-
}
|
|
1228
|
-
if (report.overBudget) warnings.push(`the skill listing is ${report.listingChars} chars (~${estTokens(report.listingChars)} tokens) against a ~${report.budgetChars}-char budget — Claude Code truncates entries past it and routing degrades.`);
|
|
1229
|
-
return {
|
|
1230
|
-
name: 'skill frontmatter parses (task 1003548)',
|
|
1231
|
-
ok: violations.length === 0,
|
|
1232
|
-
hardFail: violations.length > 0,
|
|
1233
|
-
violations,
|
|
1234
|
-
warnings,
|
|
1235
|
-
note: `${report.results.length} SKILL.md file(s) under .claude/skills/ + modules/*/skills/ parse as YAML (name + description present, no ": " / " #" in a plain scalar); length + listing budget advisory.`,
|
|
1236
|
-
};
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
// ============================================================================
|
|
1240
|
-
// Check 35 — no raw NUL byte in tracked publishable text (task 1002854)
|
|
1241
|
-
// ============================================================================
|
|
1242
|
-
//
|
|
1243
|
-
// scripts/public-mirror-export.js decides binary-vs-text by sniffing for a NUL byte in
|
|
1244
|
-
// the first 8 KiB (`isBinary`, ~line 86), and `redactBlob` skips `redactText` entirely
|
|
1245
|
-
// for anything it classifies binary. So a TEXT source containing a raw NUL is published
|
|
1246
|
-
// to the public AGPL mirror WITHOUT REDACTION.
|
|
1247
|
-
//
|
|
1248
|
-
// WHAT THIS IS AND IS NOT. The binary branch is not unguarded: it still leak-scans the
|
|
1249
|
-
// blob's latin1 view, so an embedded instance literal trips the gate. But the gate uses
|
|
1250
|
-
// `sensitiveLiterals` — raw substrings — while `redactText` applies the full `rules` set.
|
|
1251
|
-
// The exposure is therefore the DELTA between them: anything redaction would have
|
|
1252
|
-
// rewritten but the literal gate does not recognise ships verbatim. That is a latent
|
|
1253
|
-
// unredacted-publish, not a live one, which is why this is a lint rather than a fix.
|
|
1254
|
-
//
|
|
1255
|
-
// THE CLASS RECURS, WHICH IS THE ARGUMENT FOR A LINT RATHER THAN ANOTHER FIX.
|
|
1256
|
-
// Task 1703 found and fixed three instances, all the same mistake: a raw NUL used as a
|
|
1257
|
-
// join delimiter instead of the `\u0000` escape. Task 1002507 fixed a fourth in session
|
|
1258
|
-
// digests. Open idea 1000523 covers a fifth (search-ingest rollback). This check found
|
|
1259
|
-
// four more — modules/copy-desk/proposals.js, scripts/gds/claim.js,
|
|
1260
|
-
// scripts/gds/probe-cache.js and tests/copy_inventory.mjs — fixed in the same commit so
|
|
1261
|
-
// the check lands green. Nothing prevented any of them; nothing would prevent the next.
|
|
1262
|
-
//
|
|
1263
|
-
// The fix is always the same and never changes behaviour: `\u0000` compiles to exactly
|
|
1264
|
-
// the same string, so hashes, joins and regex ranges are byte-identical at runtime. Only
|
|
1265
|
-
// the SOURCE stops carrying the byte.
|
|
1266
|
-
//
|
|
1267
|
-
// SCOPE. Tracked files only (git ls-files — an untracked scratch file is not published),
|
|
1268
|
-
// with publishable text extensions. Binary formats are out of scope by definition: a PNG
|
|
1269
|
-
// is *supposed* to contain NULs and the mirror is right to pass it through.
|
|
1270
|
-
const NUL_TEXT_EXTS = ['.js', '.mjs', '.cjs', '.mts', '.md', '.sql', '.json'];
|
|
1271
|
-
|
|
1272
|
-
// Exemptions must be justified, not just listed. There are none today, and that is the
|
|
1273
|
-
// preferred state: the fix is a one-character escape with no behavioural cost, so
|
|
1274
|
-
// "exempt it" should always lose to "escape it". Kept as a named, empty constant so a
|
|
1275
|
-
// future addition is a visible, reviewable edit rather than a quiet change to a regex.
|
|
1276
|
-
const NUL_EXEMPT_PATHS = [];
|
|
1277
|
-
|
|
1278
|
-
function scanForRawNul(root, { listFiles, readFile } = {}) {
|
|
1279
|
-
const list = listFiles || (() => execFileSync('git', ['ls-files', '-z'], {
|
|
1280
|
-
cwd: root, encoding: 'latin1', maxBuffer: 1 << 26,
|
|
1281
|
-
}).split('\u0000').filter(Boolean));
|
|
1282
|
-
const read = readFile || ((f) => fs.readFileSync(path.join(root, f)));
|
|
1283
|
-
|
|
1284
|
-
const hits = [];
|
|
1285
|
-
for (const f of list()) {
|
|
1286
|
-
if (!NUL_TEXT_EXTS.includes(path.extname(f))) continue;
|
|
1287
|
-
if (NUL_EXEMPT_PATHS.some((e) => f === e || f.startsWith(e))) continue;
|
|
1288
|
-
let buf;
|
|
1289
|
-
try { buf = read(f); } catch (_) { continue; } // deleted-but-tracked, or unreadable
|
|
1290
|
-
const at = buf.indexOf(0);
|
|
1291
|
-
if (at === -1) continue;
|
|
1292
|
-
// Report the LINE, not the byte offset — a byte offset is not actionable.
|
|
1293
|
-
const line = buf.slice(0, at).toString('latin1').split('\n').length;
|
|
1294
|
-
hits.push(`${f}:${line} — raw NUL byte; use the \\u0000 escape (same string at runtime, no NUL in source)`);
|
|
1295
|
-
}
|
|
1296
|
-
return hits;
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
|
-
function checkNoRawNulInText() {
|
|
1300
|
-
let violations = [];
|
|
1301
|
-
let note = '';
|
|
1302
|
-
try {
|
|
1303
|
-
violations = scanForRawNul(REPO_ROOT);
|
|
1304
|
-
note = `tracked ${NUL_TEXT_EXTS.join('/')} sources carry no raw NUL byte, so none can be misclassified `
|
|
1305
|
-
+ 'as binary and skip public-mirror redaction (task 1002854).';
|
|
1306
|
-
} catch (e) {
|
|
1307
|
-
// Never let the scan itself fail the build — a git failure is not a boundary breach.
|
|
1308
|
-
return {
|
|
1309
|
-
name: 'no raw NUL byte in tracked publishable text (task 1002854)',
|
|
1310
|
-
ok: true, hardFail: false, violations: [], warnings: [`skipped: ${e.message}`],
|
|
1311
|
-
note: 'could not list tracked files — check skipped.',
|
|
1312
|
-
};
|
|
1313
|
-
}
|
|
1314
|
-
return {
|
|
1315
|
-
name: 'no raw NUL byte in tracked publishable text (task 1002854)',
|
|
1316
|
-
ok: violations.length === 0,
|
|
1317
|
-
hardFail: violations.length > 0,
|
|
1318
|
-
violations,
|
|
1319
|
-
warnings: [],
|
|
1320
|
-
note,
|
|
1321
|
-
};
|
|
1322
|
-
}
|
|
1323
|
-
|
|
1324
|
-
const CHECKS = [
|
|
1325
|
-
checkCoreHostBoundary,
|
|
1326
|
-
checkNoRawNulInText, // Check 35 — task 1002854: a raw NUL makes the mirror skip redaction
|
|
1327
|
-
checkClaudeMdBudget,
|
|
1328
|
-
// Check 32 — task 1002990 / criterion wa6-kernel-and-packs: the root CLAUDE.md is
|
|
1329
|
-
// now a role-neutral KERNEL and each craft's playbook lives in a pack under
|
|
1330
|
-
// docs/packs/. claim.js resolves the pack through the role registry and fails
|
|
1331
|
-
// OPEN, so a pack path that points at nothing is invisible at runtime — CI is the
|
|
1332
|
-
// only place a hollowed-out role can be caught. Rationale in that file.
|
|
1333
|
-
require('./role-pack-guard.js').checkRolePacks,
|
|
1334
|
-
checkSkillFrontmatter,
|
|
1335
|
-
checkNestedDocsPresent,
|
|
1336
|
-
checkRankGuards,
|
|
1337
|
-
checkModulePinKeysResolve,
|
|
1338
|
-
checkGeneratedArtifactsFresh,
|
|
1339
|
-
checkDeterministicRoutines,
|
|
1340
|
-
checkCoreNeverImportsModule,
|
|
1341
|
-
checkModulesImportOnlyApi,
|
|
1342
|
-
checkScopeMapImportsProtected,
|
|
1343
|
-
// Check 36 — task 1002900: a carved module with no roster key walls nothing. Extracted
|
|
1344
|
-
// to its own file (the role-pack-guard.js precedent) to keep fitness.js under the size ratchet.
|
|
1345
|
-
() => require('./scope-roster-guard.js').checkScopeRosterCoversModules({ repoRoot: REPO_ROOT, discoveredModuleKeys }),
|
|
1346
|
-
checkCoreCarriesNoModuleCode,
|
|
1347
|
-
checkKernelImportsNoDomain,
|
|
1348
|
-
checkModuleMigrationsAdditive,
|
|
1349
|
-
checkMigrationNamespacing, // Check 11b — ADR 0108 §5 cross-repo migration filenames + stem collision
|
|
1350
|
-
checkDesignContract,
|
|
1351
|
-
checkKernelPromptsNoHardcodedIdentity, // BV1.R76 — kernel prompts read identity from branding()
|
|
1352
|
-
checkNeutralConfigsNoHostIdentity, // Check 15b — BV1.R102: .json is outside the scan above
|
|
1353
|
-
checkHallSectionRegistry,
|
|
1354
|
-
checkCoreRequiresExcludedConfig, // task 1824 — core→instance-config require guard
|
|
1355
|
-
checkCoreRequiresExcludedModule, // Check 16b — task 2135: core→excluded-module require guard (R89 split)
|
|
1356
|
-
checkErrorEnvelope, // Check 17 — BV1 R03 / task 1990: no route hand-rolls a flat error (ADR 0116)
|
|
1357
|
-
checkVocabularyWall, // Check 19 — ADR 0174 / goal 1000068 R07: "role" is a craft, never a rank
|
|
1358
|
-
checkGoalMembershipVocabulary, // Check 19b — ADR 0177 / task 1003013: the FOURTH "role" (goal membership)
|
|
1359
|
-
checkGovernmentRenameIdentity, checkPrelaunchVocabulary, // 19c task 1003120 (`X`→`X` rename arrow) + 19d task 1003152 ("stealth" is the product's word) — sharing a line: this file is AT the 1,500 budget (Check 23/24 precedent below; task 1003825 buys it back)
|
|
1360
|
-
checkWriteRoutesValidated, // Check 18 — BV1 R12 / task 1999: every body-reading write route validates (ADR 0118)
|
|
1361
|
-
require('./fitness-ratchets.js').checkQualityRatchets, // Check 20 — task 1003129: quality budgets only tighten (mechanics + knip CI step live in fitness-ratchets.js)
|
|
1362
|
-
require('./doc-control-claims.js').checkDocControlClaims, // Check 37 — task 1003418 / audit A14: a doc cannot describe an enforcement control that does not exist (derived from the docs, not a hand list)
|
|
1363
|
-
require('./doc-cli-guard.js').checkDocNamesRealCli, // Check 22 — task 1003165 / G01: a doc that names a CLI invocation must match the real CLI
|
|
1364
|
-
require('./skill-preflight.js').checkOpsSkillsDeclareMachine, // Check 23 — task 1003167 / G03: an ops skill declares the machine it needs
|
|
1365
|
-
// Check 24 — task 1003166 / G02: no ops script hardcodes a version id. It landed
|
|
1366
|
-
// sharing Check 23's line, deliberately, because fitness.js was ~500 lines over
|
|
1367
|
-
// the excess-lines ratchet and a new check could not afford one (idea 1000810).
|
|
1368
|
-
// Task 1003206 carved this file from 2,004 lines to ~1,350, so that toll is paid
|
|
1369
|
-
// and the check gets its own line back.
|
|
1370
|
-
require('./version-literal-guard.js').checkNoVersionLiterals,
|
|
1371
|
-
require('./dev-box-guard.js').checkNoDevBox, // task 1003899 / ADR 0346: the retired dev box stays out (its exemption list lives in that file)
|
|
1372
|
-
require('./control-manifest.js').checkControlsExist, // Check 21 — task 1003131: goal-1000076 controls assert their own existence (the ADR 0022 assurance-of-assurance)
|
|
1373
|
-
require('./routine-schedule.js').checkRoutineCadencesScheduled, // Check 25 — task 1003209: a routine that declares a cadence must have a scheduler firing it AT that period (ADR 0188)
|
|
1374
|
-
require('./baseline-staleness.js').checkBaselineFloors, // Check 26 — task 1003210: a shrink-only baseline that never shrinks is unmanaged debt; a floor exempting one must say why
|
|
1375
|
-
require('./client-baseurl-guard.js').checkClientBaseUrl,
|
|
1376
|
-
require('./route-shadow-guard.js').checkNoRouteShadowing, // Check 31 — task 1003747: a `:param` route must not swallow a literal route mounted after it (cross-module mount order; the rot feed shipped dead this way). Rationale in that file.
|
|
1377
|
-
require('./test-path-guard.js').checkTestsUseFileUrlToPath, // Check 30 — task 1002889: a test builds its repo root with fileURLToPath, never URL.pathname (a %20 or a Windows drive slash makes require() throw at load; CI's spaceless checkout can't see it)
|
|
1378
|
-
// Check 29 — task 1003275 / ADR 0189: a work category ORIENTS a human and steers
|
|
1379
|
-
// Claude; it authorises nothing. The owner said so twice, and the goal's own prose
|
|
1380
|
-
// predicts the failure: a second thing that looks like a hierarchy gets mistaken
|
|
1381
|
-
// for one within a release. A comment cannot refuse the line that does it.
|
|
1382
|
-
require('./category-advisory-guard.js').checkCategoryIsAdvisory, // Check 27 — task 1003263: a page must not combine baseUrl:'' with a generated namespaced call (that pairing 404s every request; three pages shipped it, two of them dead in prod)
|
|
1383
|
-
// Check 28 — task 1001654 / ADR 0095: does each source file open with a module
|
|
1384
|
-
// header saying what it does and why. ADVISORY ONLY (never hardFail) — a
|
|
1385
|
-
// doc-comment gate that blocks a ship buys filler prose, not understanding.
|
|
1386
|
-
// Making it blocking is an owner decision and needs its own ADR.
|
|
1387
|
-
require('./doc-comment-coverage.js').checkDocCommentCoverage,
|
|
1388
|
-
// Check 31 — task 1003164: two ADRs may not share a number, and docs/adr/README.md
|
|
1389
|
-
// must agree with the tree. The ADR half of the guard Check 11b already gives
|
|
1390
|
-
// migrations: same shared, monotonic, human-allocated number line, and until this
|
|
1391
|
-
// landed only one of the two was enforced. An ADR number is a citation target, so a
|
|
1392
|
-
// duplicate is wrong forever (ADR 0195).
|
|
1393
|
-
// Check 33 — task 1003819: a module declares what it contributes, and nothing
|
|
1394
|
-
// checked that a declared seam is actually WIRED. verifyPortsSatisfied asks the
|
|
1395
|
-
// opposite question (every `consumes` has a provider) and validateManifest checks
|
|
1396
|
-
// only the SHAPE, so a contributes entry whose artifact was never shipped — or was
|
|
1397
|
-
// renamed out from under the manifest — boots silent: every consumer skips it the
|
|
1398
|
-
// same way it correctly skips a real declarative-only entry. CI, not boot: nothing
|
|
1399
|
-
// crashes later, so a start-up refusal would trade an outage risk for a cosmetic
|
|
1400
|
-
// one (ADR 0289). Rationale + the seam→consumer table live in that file.
|
|
1401
|
-
require('./seam-wiring-guard.js').checkSeamWiring,
|
|
1402
|
-
require('./home-isolation-guard.js').checkHomeIsolation, // Check 34 — task 1003763: a test that sets HOME for a child without USERPROFILE isolates NOTHING on win32, so it silently stops testing what its comment says. Three tasks fixed this one site at a time. Rationale in that file.
|
|
1403
|
-
...['checkDevsecopsOwnsItsChecks', 'checkEveryModuleDirIsScoped', 'checkNoNewUnownedRoot'].map((k) => require('./scope-map-guard.js')[k]), // Check 35 — task 1003949: a check file no MODULE_SCOPE_MAP key owns cannot be authorized by the goal scoped to own it, and the list drifts once per new check. Check 36 — task 1004132: the same defect one level up, a carved module whose own directory no key claims (modules/specialities/ shipped that way). Sharing the line per the ratchet convention above. Rationale in that file.
|
|
1404
|
-
require('./adr-namespace.js').checkAdrNumbering, require('./exec-path-guard.js').checkExecPathsStatic, // Check 32 — task 1003371 / B50: what the server EXECUTES, out of whose tree — the blind spot all three 2026-08-29 CRITICALs shared. Rationale + reviewed exemptions live in that file. Sharing Check 31's line (the 19c/19d + 23/24 precedent above): fitness.js is AT the 1,500 ratchet and a new check cannot afford a line until task 1003825 buys it back.
|
|
1405
|
-
];
|
|
1406
|
-
|
|
1407
|
-
function runAll() {
|
|
1408
|
-
return runChecks(CHECKS); // task 1004737: an installed core has no core source to measure — one skipped result, not a crash
|
|
1409
|
-
}
|
|
1410
|
-
|
|
1411
|
-
function main() {
|
|
1412
|
-
const results = runAll();
|
|
1413
|
-
if (process.argv.includes('--json')) {
|
|
1414
|
-
process.stdout.write(JSON.stringify(results, null, 2) + '\n');
|
|
1415
|
-
} else {
|
|
1416
|
-
console.log('Architecture fitness functions (Path C / ADR 0062 §9)\n');
|
|
1417
|
-
for (const r of results) {
|
|
1418
|
-
const mark = r.hardFail ? '✗ FAIL' : (r.warnings.length ? '! WARN' : '✓ PASS');
|
|
1419
|
-
console.log(`${mark} ${r.name}`);
|
|
1420
|
-
console.log(` ${r.note}`);
|
|
1421
|
-
for (const v of r.violations) console.log(` ✗ ${v}`);
|
|
1422
|
-
for (const w of r.warnings) console.log(` ! ${w}`);
|
|
1423
|
-
}
|
|
1424
|
-
const failed = results.filter((r) => r.hardFail).length;
|
|
1425
|
-
console.log(`\n${failed ? `${failed} check(s) FAILED` : 'all checks passed'}.`);
|
|
1426
|
-
}
|
|
1427
|
-
process.exit(results.some((r) => r.hardFail) ? 1 : 0);
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
if (require.main === module) main();
|
|
1431
|
-
|
|
1432
|
-
module.exports = {
|
|
1433
|
-
scanForRawNul,
|
|
1434
|
-
checkVocabularyWall, VOCAB_ALLOW, VOCAB_CITATION, VOCAB_EXTS, vocabFilesToScan,
|
|
1435
|
-
checkGoalMembershipVocabulary, GOAL_VOCAB_SURFACE, checkGovernmentRenameIdentity, RENAME_IDENTITY_RE, checkPrelaunchVocabulary, PRELAUNCH_SURFACE, // 19c task 1003120, 19d task 1003152
|
|
1436
|
-
runAll,
|
|
1437
|
-
resolvesToHostGame,
|
|
1438
|
-
checkCoreHostBoundary,
|
|
1439
|
-
checkClaudeMdBudget,
|
|
1440
|
-
checkNestedDocsPresent,
|
|
1441
|
-
checkRankGuards,
|
|
1442
|
-
checkModulePinKeysResolve,
|
|
1443
|
-
checkGeneratedArtifactsFresh,
|
|
1444
|
-
checkDeterministicRoutines,
|
|
1445
|
-
checkCoreNeverImportsModule,
|
|
1446
|
-
checkModulesImportOnlyApi,
|
|
1447
|
-
checkScopeMapImportsProtected,
|
|
1448
|
-
checkCoreCarriesNoModuleCode,
|
|
1449
|
-
checkKernelImportsNoDomain,
|
|
1450
|
-
checkModuleMigrationsAdditive,
|
|
1451
|
-
checkMigrationNamespacing, // Check 11b — ADR 0108 §5 cross-repo migration filenames
|
|
1452
|
-
checkAdrNumbering: require('./adr-namespace.js').checkAdrNumbering, // Check 31 — task 1003164 / ADR 0195: ADR numbers unique + index agrees with the tree
|
|
1453
|
-
checkDesignContract,
|
|
1454
|
-
checkKernelPromptsNoHardcodedIdentity, // BV1.R76 / task 1705
|
|
1455
|
-
scanPromptIdentity, // BV1.R76 — negative-test hook
|
|
1456
|
-
stripCommentsForIdentity, // task 1705 — comment-strip helper (tested)
|
|
1457
|
-
checkNeutralConfigsNoHostIdentity, // Check 15b — BV1.R102 (tested)
|
|
1458
|
-
checkHallSectionRegistry,
|
|
1459
|
-
scanHallSectionRegistry,
|
|
1460
|
-
hallMainSlice,
|
|
1461
|
-
parseZoneBudgets, // task 2177 — hall Home zone budgets (tested)
|
|
1462
|
-
scanHallZoneCounts,
|
|
1463
|
-
checkHallZoneBudgets,
|
|
1464
|
-
checkErrorEnvelope, // Check 17 — BV1 R03 / task 1990 (ADR 0116)
|
|
1465
|
-
scanFlatErrorSites, // shared with the R04 sweep + its test
|
|
1466
|
-
countFlatErrors, // per-text detector (tested)
|
|
1467
|
-
FLAT_ERROR_BASELINE,
|
|
1468
|
-
checkWriteRoutesValidated, // Check 18 — BV1 R12 / task 1999 (ADR 0118)
|
|
1469
|
-
scanUnvalidatedWriteRoutes, // shared with its test
|
|
1470
|
-
WRITE_VALIDATION_EXEMPT,
|
|
1471
|
-
scanScopeMapSource,
|
|
1472
|
-
scanKernelForModuleKeys,
|
|
1473
|
-
kernelDomainImport,
|
|
1474
|
-
KERNEL_FILES,
|
|
1475
|
-
discoveredModuleKeys,
|
|
1476
|
-
manifestModuleKeys, manifestlessModuleDirs, // task 1002790 — narrow defn + the difference
|
|
1477
|
-
moduleMigrationViolations,
|
|
1478
|
-
moduleNamespace,
|
|
1479
|
-
resolvesToModule,
|
|
1480
|
-
moduleImportViolation,
|
|
1481
|
-
moduleOwnerOf,
|
|
1482
|
-
// test/ratchet hook: toggle the module boundary enforce flag. Default is now
|
|
1483
|
-
// ENFORCING (BV1.R45 / task 1414); tests that need warn-mode restore the
|
|
1484
|
-
// default in a finally.
|
|
1485
|
-
_setModuleBoundaryEnforcing: (v) => { MODULE_BOUNDARY_ENFORCING = !!v; },
|
|
1486
|
-
scanDeterministicBody,
|
|
1487
|
-
HOST_GAME,
|
|
1488
|
-
GRANDFATHERED,
|
|
1489
|
-
LEGACY_NAMESPACED,
|
|
1490
|
-
ROOT_HARD_MAX,
|
|
1491
|
-
ROOT_TARGET,
|
|
1492
|
-
ROOT_CHAR_HARD_MAX,
|
|
1493
|
-
ROOT_CHAR_TARGET,
|
|
1494
|
-
HIGH_TRAFFIC,
|
|
1495
|
-
};
|
|
7
|
+
require('../bongos/forwarder.js').forward(module, 'fitness.js');
|