@bongos/core 1.21.175 → 1.21.176
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 +3551 -1516
- 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 +14 -14
- 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/docs/adr/0029-status-page-outage-resilience.md +6 -6
- 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 +3 -3
- 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 +89 -88
- package/docs/handoff-template.md +4 -4
- package/docs/module-api-changelog.md +5 -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 +2 -2
- package/docs/onboarding/diagrams/assertions.json +2 -2
- 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 +10 -9
- 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/gauge.js +1 -1
- package/modules/autonomy/governor-docket.js +2 -2
- package/modules/autonomy/pollers/routine-timers.js +3 -3
- package/modules/autonomy/routes/autonomy.js +3 -3
- 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 +172 -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/artifact-staleness.js +267 -0
- package/scripts/bongos/ask.js +231 -0
- package/scripts/bongos/audit-authorship.sh +329 -0
- package/scripts/bongos/audit-deps.js +189 -0
- package/scripts/bongos/audit-gate.js +121 -0
- package/scripts/bongos/audit-rank-roles.js +172 -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/classify-discipline.js +153 -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 +381 -0
- package/scripts/bongos/codemod-rename-src-gds.js +145 -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/coreB-carve-proof.sh +725 -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 +343 -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-names.js +102 -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 +336 -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-goals.js +109 -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 +283 -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-adopt-tasks.js +75 -0
- package/scripts/bongos/seed-api-contract-goal-tasks.js +141 -0
- package/scripts/bongos/seed-board-room-tasks.js +196 -0
- package/scripts/bongos/seed-bongos-app-tasks.js +294 -0
- package/scripts/bongos/seed-bongos-coreB-tranche1-tasks.js +81 -0
- package/scripts/bongos/seed-bongos-coreB-tranche2-tasks.js +100 -0
- package/scripts/bongos/seed-bongos-goal-hierarchy-tasks.js +307 -0
- package/scripts/bongos/seed-bongos-module-system-tasks.js +346 -0
- package/scripts/bongos/seed-bongos-tasks.js +214 -0
- package/scripts/bongos/seed-bongos-v1-idea-routing-tasks.js +152 -0
- package/scripts/bongos/seed-bongos-v1-seo-tasks.js +104 -0
- package/scripts/bongos/seed-bv1-community-tasks.js +131 -0
- package/scripts/bongos/seed-bv1-privacy-invites-tasks.js +133 -0
- package/scripts/bongos/seed-bv1-profile-page-tasks.js +161 -0
- package/scripts/bongos/seed-bv1-profiles-tasks.js +135 -0
- package/scripts/bongos/seed-bv1-r01-delta-tasks.js +154 -0
- package/scripts/bongos/seed-bv2-ideator-surface-tasks.js +390 -0
- package/scripts/bongos/seed-bv2-tweak-mode-tasks.js +277 -0
- package/scripts/bongos/seed-gds-v4-tasks.js +624 -0
- package/scripts/bongos/seed-governance-tasks.js +340 -0
- package/scripts/bongos/seed-medusa-tasks.js +440 -0
- package/scripts/bongos/seed-module-upstreaming.js +219 -0
- package/scripts/bongos/seed-productization-tasks.js +235 -0
- package/scripts/bongos/seed-project-admin-console-tasks.js +88 -0
- package/scripts/bongos/seed-provisioning-tasks.js +83 -0
- package/scripts/bongos/seed-staging.sh +117 -0
- package/scripts/bongos/seed-strict-versioning-tasks.js +275 -0
- package/scripts/bongos/seed-v2-world-tasks.js +283 -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 +292 -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/artifact-staleness.js +5 -265
- 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/classify-discipline.js +6 -152
- 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/codemod-rename-src-gds.js +6 -144
- 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/coreB-carve-proof.sh +7 -724
- 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-names.js +5 -100
- 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-goals.js +5 -107
- 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-adopt-tasks.js +6 -74
- package/scripts/gds/seed-api-contract-goal-tasks.js +6 -140
- package/scripts/gds/seed-board-room-tasks.js +6 -196
- package/scripts/gds/seed-bongos-app-tasks.js +6 -293
- package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +6 -80
- package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +6 -99
- package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +6 -306
- package/scripts/gds/seed-bongos-module-system-tasks.js +6 -345
- package/scripts/gds/seed-bongos-tasks.js +6 -213
- package/scripts/gds/seed-bongos-v1-idea-routing-tasks.js +6 -152
- package/scripts/gds/seed-bongos-v1-seo-tasks.js +6 -104
- package/scripts/gds/seed-bv1-community-tasks.js +6 -131
- package/scripts/gds/seed-bv1-privacy-invites-tasks.js +6 -133
- package/scripts/gds/seed-bv1-profile-page-tasks.js +6 -161
- package/scripts/gds/seed-bv1-profiles-tasks.js +6 -135
- package/scripts/gds/seed-bv1-r01-delta-tasks.js +6 -154
- package/scripts/gds/seed-bv2-ideator-surface-tasks.js +6 -390
- package/scripts/gds/seed-bv2-tweak-mode-tasks.js +6 -277
- package/scripts/gds/seed-gds-v4-tasks.js +6 -623
- package/scripts/gds/seed-governance-tasks.js +6 -339
- package/scripts/gds/seed-medusa-tasks.js +6 -439
- package/scripts/gds/seed-module-upstreaming.js +5 -217
- package/scripts/gds/seed-productization-tasks.js +6 -234
- package/scripts/gds/seed-project-admin-console-tasks.js +6 -88
- package/scripts/gds/seed-provisioning-tasks.js +6 -82
- package/scripts/gds/seed-staging.sh +7 -116
- package/scripts/gds/seed-strict-versioning-tasks.js +6 -274
- package/scripts/gds/seed-v2-world-tasks.js +6 -282
- 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/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/artifact_staleness.mjs +9 -9
- 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_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 +58 -58
- 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 +3 -3
- 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_names.mjs +2 -2
- 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/newcomer_generator.mjs +48 -0
- 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 +6 -6
- package/tests/routine_schedule.mjs +9 -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/audit-exports.js +0 -128
- package/scripts/gds/resolve-skill-model.js +0 -57
- package/scripts/gds/security-baseline-check.sh +0 -180
- package/scripts/gds/spike-task-map.js +0 -899
- package/scripts/status-probe.mjs +0 -213
- package/src/bongos/uptime-poller.js +0 -93
- 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
|
@@ -0,0 +1,1130 @@
|
|
|
1
|
+
// scripts/bongos/ship-land.js — the land outcome type and the ci-land paths (local, server-mediated) + their polling.
|
|
2
|
+
//
|
|
3
|
+
// Carved out of scripts/bongos/ship.js by task 1003205 (goal 1000079, the R03
|
|
4
|
+
// de-monolith plan) — a STRUCTURAL move, not a rewrite: the code below is the
|
|
5
|
+
// original ship.js lines 990-1468 unchanged. ship.js remains the facade that
|
|
6
|
+
// re-exports every name and owns the CLI entry point, so the ship contract and
|
|
7
|
+
// every flag are untouched, and the other scripts that import from it are too.
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const fs = require('node:fs');
|
|
12
|
+
const os = require('node:os');
|
|
13
|
+
const path = require('node:path');
|
|
14
|
+
const { cliClient } = require('./cli-lib');
|
|
15
|
+
const { gitArgvOk, gitOk, sanitizeGitHubRefs, shellOk } = require('./ship-git.js');
|
|
16
|
+
const { buildPrCreateArgv, buildPrMergeArgv, deployRunSucceeded, deployedCommitStatus, fetchDeployedVersion, ghArgvOk, ghJson, pushVia, resolveInstanceBase } = require('./ship-deploy-target.js');
|
|
17
|
+
const { normalizeApiError } = require('./ship-io.js');
|
|
18
|
+
const { plainCardLines } = require('./plain-cards.js');
|
|
19
|
+
// The server's own reader of a PR's check rollup (task 1003988), reused so the laptop
|
|
20
|
+
// poll names a red PR exactly the way publish-status does (task 1003764). Dependency-free.
|
|
21
|
+
const { readCheckRollup, UNIT_REPORT_CONTEXT, RED_CONCLUSIONS } = require('../../modules/lifecycle/check-rollup.js');
|
|
22
|
+
const { prMergeSentence } = require('../../modules/lifecycle/page-tweak-hold.js');
|
|
23
|
+
|
|
24
|
+
// ---------- the land outcome (task 1002541, part 1) ----------
|
|
25
|
+
//
|
|
26
|
+
// The land chain used to answer with a bare boolean. Every bail site already
|
|
27
|
+
// computes a precise reason and logs it, but `false` threw that reason away — so
|
|
28
|
+
// the completion card had only the task's STATUS to go on ('confirmed') and
|
|
29
|
+
// printed "Deploy landing automatically" even when nothing was landing and the
|
|
30
|
+
// builder was, under ADR 0120, unpaid. The failure announced itself as success.
|
|
31
|
+
//
|
|
32
|
+
// "Not shipped" is not one thing, so this is a three-way, not a boolean:
|
|
33
|
+
// landed() — merged + deployed; the task flips to shipped.
|
|
34
|
+
// landPending() — published and auto-merge armed: it DOES land on its own
|
|
35
|
+
// (CI / the server reconciler), so "landing automatically"
|
|
36
|
+
// is honest here. A poll timeout is this, not a failure
|
|
37
|
+
// (task 1049) — keep it out of the loud path.
|
|
38
|
+
// landBailed(r, n) — nothing is landing. `r` is the reason already logged,
|
|
39
|
+
// `n` the command that recovers it.
|
|
40
|
+
// Only landBailed makes the card say NOT landed. Purely additive: no bail site
|
|
41
|
+
// changes what it DOES, only what it now reports back.
|
|
42
|
+
// ADR 0184: an EMPTY ship has no commit to prove, so it must DECLARE itself.
|
|
43
|
+
// task 1002572 (PART 2): a bail also carries an optional `bailId` — the stable
|
|
44
|
+
// name of WHICH refusal fired, so a caller can route the recoverable ones to the
|
|
45
|
+
// push+PR path instead of stranding. `null` for every un-tagged bail, which keeps
|
|
46
|
+
// them terminal (fail-safe: an untagged bail never gains a silent fallback).
|
|
47
|
+
function landed(o = {}) { return { ok: true, pending: false, reason: null, nextStep: null, noArtifact: o.noArtifact === true, noArtifactReason: o.noArtifactReason || null }; }
|
|
48
|
+
function landPending() { return { ok: false, pending: true, reason: null, nextStep: null }; }
|
|
49
|
+
function landBailed(reason, nextStep = null, bailId = null) { return { ok: false, pending: false, reason, nextStep, bailId }; }
|
|
50
|
+
// task 1004322 (ADR 0341 D7): the FOURTH outcome, and only a page tweak reaches it.
|
|
51
|
+
// Its grade passed and its branch and PR are published, but nothing is landing and
|
|
52
|
+
// nothing should: the artist approves the applied page first. Not a bail (nothing
|
|
53
|
+
// failed, and the card must not say "Land it") and not pending (no auto-merge is
|
|
54
|
+
// armed, so it does not land on its own).
|
|
55
|
+
function landHeld({ prUrl = null } = {}) { return { ok: false, pending: false, held: true, reason: null, nextStep: null, prUrl }; }
|
|
56
|
+
|
|
57
|
+
// ---------- which bails a PR can still land (task 1002572, part 2) ----------
|
|
58
|
+
//
|
|
59
|
+
// A builder in a SINGLE main checkout can never complete a local merge: the tree
|
|
60
|
+
// that would RECEIVE the merge is the very tree holding the feature branch. That
|
|
61
|
+
// is a property of the machine, not of the work — the branch itself is perfectly
|
|
62
|
+
// landable, just not from here. So that one bail must fall back to the push+PR
|
|
63
|
+
// path (ciLand) rather than parking the task at 'confirmed' unpaid (ADR 0120).
|
|
64
|
+
//
|
|
65
|
+
// Everything else stays LOUD. A merge conflict, a red post-merge smoke, a failed
|
|
66
|
+
// push, an unreachable origin: those are real failures, and a PR would carry the
|
|
67
|
+
// same breakage to main. Membership is opt-in by id for exactly that reason —
|
|
68
|
+
// blanket-converting bails into PRs is the way this fix goes wrong.
|
|
69
|
+
const LAND_BAIL_MAIN_CHECKOUT_ON_BRANCH = 'main-checkout-on-branch';
|
|
70
|
+
const LAND_BAIL_NO_TASK_BRANCH = 'no-task-branch';
|
|
71
|
+
const PR_RECOVERABLE_BAILS = new Set([LAND_BAIL_MAIN_CHECKOUT_ON_BRANCH]);
|
|
72
|
+
|
|
73
|
+
// landBailRecoverableByPr — PURE. Can this bail still be landed by opening a PR?
|
|
74
|
+
// `no-task-branch` is deliberately NOT in the set: standing on main there is no
|
|
75
|
+
// head branch to open a PR FROM, so the PR path has nothing to offer it (its cure
|
|
76
|
+
// is to go back to the task branch and re-ship, which now works).
|
|
77
|
+
function landBailRecoverableByPr(bailId) {
|
|
78
|
+
return PR_RECOVERABLE_BAILS.has(bailId);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// The short COMMAND form of strandNextStep (which is prose, sized for the log).
|
|
82
|
+
// The card has room for one command, not a sentence.
|
|
83
|
+
function strandCommand(taskId, via) {
|
|
84
|
+
return via === 'server' ? `node scripts/bongos/ship.js ${taskId}` : '/merge-mode';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ciLand — dispatch the 'ci' confirmed->shipped land to the local or the
|
|
88
|
+
// server-mediated path. Async because the server path awaits GDS API calls.
|
|
89
|
+
// opts.hold (task 1004322): PUBLISH ONLY — push the branch and open the PR, never
|
|
90
|
+
// arm auto-merge and never poll for a land. A page tweak held for its artist takes
|
|
91
|
+
// it; every other caller passes nothing and gets the unchanged path.
|
|
92
|
+
async function ciLand(taskId, branch, valueSummary, opts = {}) {
|
|
93
|
+
console.log(opts.hold
|
|
94
|
+
? ' held for the artist — publishing the branch and its PR only (no auto-merge, no land)'
|
|
95
|
+
: ' deploy mode: ci — landing via PR auto-merge (no droplet key needed)');
|
|
96
|
+
if (pushVia() === 'server') {
|
|
97
|
+
return ciLandServer(taskId, branch, valueSummary, opts);
|
|
98
|
+
}
|
|
99
|
+
return await ciLandLocal(taskId, branch, valueSummary, opts);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// task 1001916: render a FAILED POST /tasks/:id/publish-branch for the builder.
|
|
103
|
+
// The server has carried { step, reason } — which git step failed + the
|
|
104
|
+
// credential-scrubbed stderr — since task 1547, but the bail site printed only
|
|
105
|
+
// `data.message || data.error`: "[object Object]" on the ADR 0116 envelope, a
|
|
106
|
+
// bare `publish_failed` on the legacy flat shape. That hid a non-fast-forward
|
|
107
|
+
// rejection (the server had already freshened the branch itself) across several
|
|
108
|
+
// blind retry laps, so that case also gets its specific remedy. Pure + exported
|
|
109
|
+
// for tests/ship_publish_error.mjs (no git, no network).
|
|
110
|
+
const NON_FAST_FORWARD_RE = /fetch first|non-fast-forward/i;
|
|
111
|
+
|
|
112
|
+
// localHistoryRewritten — the discriminator formatPublishFailure needs (task 1003221).
|
|
113
|
+
// Is the remote-tracking tip an ancestor of HEAD? Yes = we only added commits, so a
|
|
114
|
+
// non-fast-forward means the SERVER moved. No = our history diverged, which is what a
|
|
115
|
+
// rebase or amend does. null = no ref to compare against, and null keeps the original
|
|
116
|
+
// wording so an unknown never invents a diagnosis.
|
|
117
|
+
function localHistoryRewritten(branch) {
|
|
118
|
+
const remoteRef = `origin/${branch}`;
|
|
119
|
+
if (!gitArgvOk(['rev-parse', '--verify', '--quiet', remoteRef], { stdio: 'ignore' })) return null;
|
|
120
|
+
// `merge-base --is-ancestor A B` exits 0 when A is an ancestor of B.
|
|
121
|
+
return !gitArgvOk(['merge-base', '--is-ancestor', remoteRef, 'HEAD'], { stdio: 'ignore' });
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// task 1003221 — a non-fast-forward has TWO causes needing OPPOSITE recoveries. This
|
|
125
|
+
// gave one diagnosis ("the server already moved <branch>") and prescribed `reset`,
|
|
126
|
+
// which is right when the server is ahead and DESTRUCTIVE when the builder rebased or
|
|
127
|
+
// amended an already-published branch — it discards the commits they just made (the
|
|
128
|
+
// real 2026-08-21 case, 163 minutes). Server-mediated publish is APPEND-ONLY, as the
|
|
129
|
+
// learning claim.js prints says. opts.localHistoryRewritten discriminates; null means
|
|
130
|
+
// git could not tell and keeps the original wording rather than guessing.
|
|
131
|
+
function formatPublishFailure(data, status, branch, opts = {}) {
|
|
132
|
+
const { code, message } = normalizeApiError(data);
|
|
133
|
+
const envelopeDetails = (data && data.error && typeof data.error === 'object' && data.error.details) || null;
|
|
134
|
+
const details = envelopeDetails || data || {};
|
|
135
|
+
const label = message || code || (data && data.message) || `HTTP ${status}`;
|
|
136
|
+
// Flattened ONLY for the matchers below and the one-line summary. The readable
|
|
137
|
+
// copy is printed verbatim underneath (task 1003222): the server no longer clips
|
|
138
|
+
// stderr, and git's useful line is the LAST one, so collapsing a 20-line push
|
|
139
|
+
// failure into a single run-on sentence hides the very thing that was un-hidden.
|
|
140
|
+
const reason = details.reason ? String(details.reason).replace(/\s+/g, ' ').trim() : '';
|
|
141
|
+
const parts = [];
|
|
142
|
+
if (details.step) parts.push(`step: ${details.step}`);
|
|
143
|
+
if (details.git_exit_code != null) parts.push(`git exit ${details.git_exit_code}`);
|
|
144
|
+
if (details.github_status != null) parts.push(`GitHub HTTP ${details.github_status}`);
|
|
145
|
+
if (details.timed_out) parts.push('TIMED OUT');
|
|
146
|
+
// The one-line summary stays short and scannable; the full text follows it.
|
|
147
|
+
if (reason) parts.push(`reason: ${reason.length > 200 ? `${reason.slice(0, 200)}…` : reason}`);
|
|
148
|
+
let out = parts.length ? `${label} (${parts.join('; ')})` : label;
|
|
149
|
+
|
|
150
|
+
// ORDER MATTERS: summary, then the REMEDY, then the verbatim block last. The
|
|
151
|
+
// remedy is the actionable sentence and must not end up stranded below twenty
|
|
152
|
+
// lines of git chatter where it reads as a footnote to the quote.
|
|
153
|
+
if (NON_FAST_FORWARD_RE.test(reason)) {
|
|
154
|
+
out += opts.localHistoryRewritten === true
|
|
155
|
+
? ` — your LOCAL history was rewritten (a rebase or amend), so ${branch} is no longer a `
|
|
156
|
+
+ `descendant of what the server already holds. Server-mediated publish is APPEND-ONLY: run `
|
|
157
|
+
+ `\`git fetch origin && git merge origin/${branch}\`, re-run the generators, commit the merge, `
|
|
158
|
+
+ 'and re-ship. Do NOT reset or re-rebase — that discards the commits you just made.'
|
|
159
|
+
: ` — the server already moved ${branch}: fetch origin, reset onto origin/${branch}, `
|
|
160
|
+
+ 're-run the generators, and re-ship so the push fast-forwards.';
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// The untruncated remote message, verbatim and indented so it reads as a quotation
|
|
164
|
+
// rather than as more ship output. Only when it is multi-line — a single-line
|
|
165
|
+
// stderr is already fully present in the summary above, and repeating it is noise.
|
|
166
|
+
const full = details.reason ? String(details.reason).trimEnd() : '';
|
|
167
|
+
if (full && /\n/.test(full)) {
|
|
168
|
+
out += `\n\n --- what the remote actually said ---\n${full.split('\n').map((l) => ` ${l}`).join('\n')}\n --- end ---`;
|
|
169
|
+
if (details.reason_bytes != null && details.reason_bytes > full.length) {
|
|
170
|
+
out += `\n (${details.reason_bytes} bytes at the server; the middle was omitted here)`;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return out;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ciLandServer — the server-mediated path: no GitHub push credential on this
|
|
177
|
+
// machine, so hand the branch to the GDS, which pushes it + opens the PR +
|
|
178
|
+
// auto-merges with the server-side credential. Needs an ordinary cli session.
|
|
179
|
+
async function ciLandServer(taskId, branch, valueSummary, { hold = false } = {}) {
|
|
180
|
+
console.log(' ci-land: server-mediated publish (this machine has no GitHub push credential)');
|
|
181
|
+
const headSha = gitOk('git rev-parse HEAD');
|
|
182
|
+
// Make sure origin/main is current so the THIN bundle's `origin/main..HEAD`
|
|
183
|
+
// base is resolvable (a read-only fetch — works on a credential-less origin).
|
|
184
|
+
gitArgvOk(['fetch', 'origin', 'main'], { stdio: 'ignore' });
|
|
185
|
+
|
|
186
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'otb-bundle-'));
|
|
187
|
+
const bundlePath = path.join(tmpDir, 'branch.bundle');
|
|
188
|
+
try {
|
|
189
|
+
if (!gitArgvOk(['bundle', 'create', bundlePath, `origin/main..${branch}`], { stdio: 'ignore' })) {
|
|
190
|
+
console.log(` ci-land: could not build the branch bundle (nothing new to push, or a git error); task stays at confirmed. ${strandNextStep(taskId, 'server')}`);
|
|
191
|
+
return landBailed('could not build the branch bundle', strandCommand(taskId, 'server'));
|
|
192
|
+
}
|
|
193
|
+
const bundleB64 = fs.readFileSync(bundlePath).toString('base64');
|
|
194
|
+
const r = await (await cliClient()).tasks.postTasksIdPublishBranch({
|
|
195
|
+
id: taskId,
|
|
196
|
+
body: { branch, head_sha: headSha, value_summary: valueSummary, bundle_b64: bundleB64 },
|
|
197
|
+
});
|
|
198
|
+
if (r.status === 503) {
|
|
199
|
+
console.log(' ci-land: server-mediated push is not configured on the server yet (no GitHub App nor GITHUB_PUSH_TOKEN — operator action, ADR 0055). Task stays at confirmed.');
|
|
200
|
+
return landBailed('server-mediated push is not configured (operator action)', strandCommand(taskId, 'server'));
|
|
201
|
+
}
|
|
202
|
+
if (!r.ok) {
|
|
203
|
+
const e = formatPublishFailure(r.data, r.status, branch, {
|
|
204
|
+
localHistoryRewritten: localHistoryRewritten(branch),
|
|
205
|
+
});
|
|
206
|
+
console.log(` ci-land: server publish failed — ${e}. Task stays at confirmed. ${strandNextStep(taskId, 'server')}`);
|
|
207
|
+
return landBailed(`server publish failed — ${e}`, strandCommand(taskId, 'server'));
|
|
208
|
+
}
|
|
209
|
+
// task 1004322: the server does not arm a held page tweak (it reads the hold
|
|
210
|
+
// itself), so do not tell the builder to merge it on GitHub.
|
|
211
|
+
console.log(hold
|
|
212
|
+
? ` ci-land: server pushed ${branch} + PR ${r.data.pr_url} (auto-merge NOT armed: waiting for the artist).`
|
|
213
|
+
: ` ci-land: server pushed ${branch} + PR ${r.data.pr_url} (auto-merge ${r.data.auto_merge ? 'enabled' : 'NOT enabled — merge it on GitHub'}).`);
|
|
214
|
+
const assigneeLine = prAssigneeLine(r.data.pr_assignee);
|
|
215
|
+
if (assigneeLine) console.log(assigneeLine);
|
|
216
|
+
if (hold) return landHeld({ prUrl: r.data.pr_url || null });
|
|
217
|
+
return pollServerPublish(taskId, branch);
|
|
218
|
+
} finally {
|
|
219
|
+
try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch (_) { /* best-effort */ }
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// task 1049 (B — async land semantics): classify a CI-land poll outcome so a
|
|
224
|
+
// SUCCESSFUL-but-still-running publish reads as success, not failure. The #1027
|
|
225
|
+
// retrospective: the ship's poll window is shorter than real CI, so a PR that was
|
|
226
|
+
// opened + auto-merge-armed (a SUCCESS) printed "did not merge — task stays at
|
|
227
|
+
// confirmed" and looked like a failure. Outcomes:
|
|
228
|
+
// 'shipped' — merged AND deploy-prod succeeded → flip the task to shipped
|
|
229
|
+
// 'failed' — PR closed without merging (a check failed / closed manually)
|
|
230
|
+
// 'pending' — PR still open with auto-merge armed (or merged, deploy not yet):
|
|
231
|
+
// NOT a failure — it lands on its own (the server reconciles the
|
|
232
|
+
// task to shipped, and a re-run resumes — task 941).
|
|
233
|
+
// Pure + exported for unit tests (no git/network). Accepts the publish-status
|
|
234
|
+
// response shape verbatim — getPublishStatus returns snake_case (pr_state,
|
|
235
|
+
// deploy_status); camelCase aliases are tolerated for test convenience.
|
|
236
|
+
// task 1002472: 'unconfigured' means the repo has no deploy-prod.yml to wait for
|
|
237
|
+
// (ADR 0108 pin-bump publishing), so the merge IS the land. Mirrors
|
|
238
|
+
// github-push.landConfirmed — kept in step by tests/ship_ci_deploy.mjs, since this
|
|
239
|
+
// CLI cannot import the server module.
|
|
240
|
+
function classifyLandOutcome(s) {
|
|
241
|
+
const merged = !!(s && s.merged);
|
|
242
|
+
const deployStatus = s && (s.deploy_status ?? s.deployStatus);
|
|
243
|
+
const prState = s && (s.pr_state ?? s.prState);
|
|
244
|
+
if (merged && (deployStatus === 'success' || deployStatus === 'unconfigured')) return 'shipped';
|
|
245
|
+
if (prState === 'closed' && !merged) return 'failed';
|
|
246
|
+
return 'pending';
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// task 1718: PURE — after ciLandLocal tries to arm GitHub auto-merge, decide which
|
|
250
|
+
// poll path lands + watches the PR. Arming auto-merge commonly FAILS when shipping
|
|
251
|
+
// from a worktree (`gh pr merge --auto` runs a git op that trips on `'main' is
|
|
252
|
+
// already used by worktree`) or with branch protection off — but the PR is open and
|
|
253
|
+
// this is NOT a dead-end: the server's merge driver + reconciler still land green
|
|
254
|
+
// PRs. So an enable-failure must NOT strand the builder at 'confirmed' (they'd never
|
|
255
|
+
// see the SHIPPED banner in-session, and the machine-global land-watch breadcrumb
|
|
256
|
+
// would surface it in some OTHER session). Instead:
|
|
257
|
+
// 'ci' → auto-merge armed: watch GitHub directly (pollCiDeploy).
|
|
258
|
+
// 'server' → auto-merge NOT armed: drive + watch the server land via publish-status
|
|
259
|
+
// (pollServerPublish) — reading it is reconcile-on-read, so it DRIVES the
|
|
260
|
+
// merge and observes the flip to 'shipped'.
|
|
261
|
+
// Both paths end at 'shipped' on a real land, so the banner renders in the shipping
|
|
262
|
+
// session and no 'confirmed' breadcrumb is written. Exported for unit tests.
|
|
263
|
+
function landPollAfterAutoMerge(autoMergeArmed) {
|
|
264
|
+
return autoMergeArmed ? 'ci' : 'server';
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// task 1719: PURE — after mergeAndDeploy runs, the completion card + the pending-land
|
|
268
|
+
// breadcrumb must reflect the AUTHORITATIVE post-land status, not the pre-merge one
|
|
269
|
+
// finishShip was handed. If the task actually reached 'shipped' in-session (a laptop
|
|
270
|
+
// sync land, the enable-success poll, or the task-1718 enable-failure server poll),
|
|
271
|
+
// the card renders the SHIPPED banner and printCompletionCard writes NO breadcrumb;
|
|
272
|
+
// otherwise keep the pre-merge status (the async land is still pending → 'confirmed' →
|
|
273
|
+
// the next-turn land-watch breadcrumb is the intended fallback). Exported for tests.
|
|
274
|
+
function reconciledCardStatus(liveStatus, preMergeStatus) {
|
|
275
|
+
return liveStatus === 'shipped' ? 'shipped' : preMergeStatus;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// task 1052 (E): the machine-appropriate next step when a ship lands the task at
|
|
279
|
+
// 'confirmed' without finishing. A machine with no push credential (pushVia 'server' —
|
|
280
|
+
// no authed gh) CANNOT run /merge-mode (it needs gh + a main checkout), so the old
|
|
281
|
+
// "for /merge-mode" advice was a dead end there (the #1027 retrospective: the agent
|
|
282
|
+
// had to reverse-engineer recovery from source). Point such a machine at the resume
|
|
283
|
+
// instead (task 941); a laptop keeps /merge-mode (with resume as the alternative).
|
|
284
|
+
// Pure + exported for unit tests.
|
|
285
|
+
function strandNextStep(taskId, via) {
|
|
286
|
+
if (via === 'server') {
|
|
287
|
+
return `Re-run \`node scripts/bongos/ship.js ${taskId}\` to resume — it picks up exactly where it stopped (task 941). ` +
|
|
288
|
+
`(/merge-mode is NOT available here — it needs gh + a main checkout this machine doesn't have.)`;
|
|
289
|
+
}
|
|
290
|
+
return `Run /merge-mode to land it — or re-run \`node scripts/bongos/ship.js ${taskId}\`, which resumes from here (task 941).`;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// The standard "published — it'll land on its own" success-pending banner
|
|
294
|
+
// (task 1049). Shared by both poll paths so the message is identical and never
|
|
295
|
+
// reads as a failure. The task legitimately stays at 'confirmed' until CI lands
|
|
296
|
+
// it; the server reconciles it to 'shipped' (publish-status reconcile-on-read)
|
|
297
|
+
// and a re-run resumes (task 941).
|
|
298
|
+
//
|
|
299
|
+
// task 1002606 (finding P-3): the banner used to end at "NOT a failure", so when
|
|
300
|
+
// a land DID fail (hand-written conflict, PR closed unmerged, persistent red
|
|
301
|
+
// check) the builder's last signal said everything was fine and the strand sat
|
|
302
|
+
// invisible until they happened to look. The banner now tells the failure story
|
|
303
|
+
// too: the server flags a strand needs_rebase (definitive shapes within a sweep,
|
|
304
|
+
// ambiguous ones at ~30 min), /builder-start warns, and new claims gate on it.
|
|
305
|
+
// Pure + exported so the wording is pinned by tests/ship_ci_deploy.mjs.
|
|
306
|
+
//
|
|
307
|
+
// task 1003764: `red` — the PR was RED on the poll's last read. "NOT a failure" is then
|
|
308
|
+
// false: a required check that failed does not pass by waiting, so the banner says the
|
|
309
|
+
// land is stuck on it and defers to the red lines above for the remedy.
|
|
310
|
+
function landPendingLines(taskId, { merged, red, notStarted } = {}) {
|
|
311
|
+
// task 1004289: CI never RAN (the account cannot run Actions). Not a failure of the
|
|
312
|
+
// work, and not something waiting fixes either: the checks have to be started again.
|
|
313
|
+
if (notStarted) {
|
|
314
|
+
return [
|
|
315
|
+
' ci-land: Published, but CI never started on the PR (GitHub ran none of its checks), so it has NOT merged',
|
|
316
|
+
' and cannot until they run. The task stays at \'confirmed\'. Nothing in the work needs to change: once the',
|
|
317
|
+
` owner restores GitHub Actions, re-run the failed jobs (lines above), then re-run \`node scripts/bongos/ship.js ${taskId}\``,
|
|
318
|
+
' to watch the land — it resumes from here (task 941).',
|
|
319
|
+
];
|
|
320
|
+
}
|
|
321
|
+
if (red) {
|
|
322
|
+
return [
|
|
323
|
+
' ci-land: Published, but the PR is RED (the check named above), so it has NOT merged and will not',
|
|
324
|
+
' until that check passes. The task stays at \'confirmed\'. Do what the lines above say, then re-run',
|
|
325
|
+
` \`node scripts/bongos/ship.js ${taskId}\` — it resumes from here (task 941). If it stays red, the server flags`,
|
|
326
|
+
' the task needs_rebase — /builder-start will warn you and new claims are gated until it lands or is released.',
|
|
327
|
+
];
|
|
328
|
+
}
|
|
329
|
+
return [
|
|
330
|
+
` ci-land: ✓ Published — auto-merge is armed${merged ? ' and the PR has merged' : ''}. This is NOT a failure.`,
|
|
331
|
+
` CI is still finishing; GitHub will ${merged ? 'deploy' : 'merge + deploy'} automatically once the required checks pass,`,
|
|
332
|
+
` and the task flips to 'shipped' on its own. Re-run \`node scripts/bongos/ship.js ${taskId}\` anytime to confirm`,
|
|
333
|
+
` it landed — it resumes from here (task 941). The task is at 'confirmed' until the deploy completes.`,
|
|
334
|
+
` If it CANNOT land on its own (a hand-written merge conflict, the PR closed without merging, a check`,
|
|
335
|
+
` that keeps failing), the server flags the task needs_rebase — /builder-start will warn you and new`,
|
|
336
|
+
` claims are gated until you fix + re-land it (re-run the ship after fixing), or release it.`,
|
|
337
|
+
];
|
|
338
|
+
}
|
|
339
|
+
function printLandPending(taskId, opts = {}) {
|
|
340
|
+
console.log('');
|
|
341
|
+
for (const line of landPendingLines(taskId, opts)) console.log(line);
|
|
342
|
+
// The land_pending card says there is nothing to do, which a red PR makes untrue; the
|
|
343
|
+
// red line already printed the failing_check card (task 1003764), or the
|
|
344
|
+
// ci_not_started one (task 1004289).
|
|
345
|
+
if (!opts.red && !opts.notStarted) for (const line of plainCardLines('land_pending')) console.log(line);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// task 1002645 — the honest close-out when the PR MERGED but the server refused the
|
|
349
|
+
// confirmed→shipped flip (reconcile_blocked: the task-1547 land proof missed — a
|
|
350
|
+
// wrong/missing published tip, or the matched PR doesn't reference this task). The
|
|
351
|
+
// optimistic "NOT a failure" banner was a lie here: without proof the auto-land can
|
|
352
|
+
// NEVER finish, and the wave-5 ships sat at 'confirmed' with their last signal
|
|
353
|
+
// saying everything was fine. Name the refusal and the remedy instead. Pure +
|
|
354
|
+
// exported so the wording is pinned by tests/ship_ci_deploy.mjs.
|
|
355
|
+
function reconcileBlockedLines(taskId, reason) {
|
|
356
|
+
return [
|
|
357
|
+
` ci-land: the PR MERGED, but the task did NOT flip to 'shipped' — the server could not prove the land is`,
|
|
358
|
+
` THIS task's: ${reason}.`,
|
|
359
|
+
` The server reconciler retries the proof every ~5 min, so a late-recorded tip or PR reference still lands`,
|
|
360
|
+
` on its own. Re-run \`node scripts/bongos/ship.js ${taskId}\` to re-drive it; if it stays blocked the server`,
|
|
361
|
+
` flags the task needs_rebase and /builder-start will show the remedy.`,
|
|
362
|
+
];
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// task 1003991 — the server opens the PR with ITS credential, so "created by me" on
|
|
366
|
+
// GitHub is empty for the builder; it assigns the PR to them instead, and this says
|
|
367
|
+
// where that makes it findable. Null when the server assigned nobody. Pure + exported.
|
|
368
|
+
function prAssigneeLine(login) {
|
|
369
|
+
return /^[A-Za-z\d_-]{1,39}$/.test(String(login || ''))
|
|
370
|
+
? ` ci-land: the PR is assigned to @${login} — on GitHub it is under Pull requests → Assigned to you (the server opened it, so "Created by you" stays empty).`
|
|
371
|
+
: null;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// task 1003988 — what to tell a builder while their PR sits RED. The poll used to
|
|
375
|
+
// wait out its nine minutes in silence, so a credential-less checkout learned only that
|
|
376
|
+
// the land was "pending" and pushed the same commit again (PR 922: nine red runs).
|
|
377
|
+
// `md` is publish-status's merge_driver; null means nothing red to report. Pure +
|
|
378
|
+
// exported so the wording is pinned by tests/unit_report_status.mjs.
|
|
379
|
+
function redPrLine(md) {
|
|
380
|
+
const reason = (md && md.reason) || '';
|
|
381
|
+
if (md && md.not_started) {
|
|
382
|
+
const job = (/^ci_not_started:(.+)$/.exec(reason) || [])[1];
|
|
383
|
+
return ` ci-land: CI NEVER RAN on this PR — GitHub did not start ${job ? `the \`${job}\` job` : 'its checks'} ("The job was not started because …", `
|
|
384
|
+
+ 'an Actions budget or billing stop on the account). Nothing in the work was tested, so there is nothing in it to fix.';
|
|
385
|
+
}
|
|
386
|
+
const fix = 'fix it, commit, and re-run the ship — re-pushing unchanged work cannot turn it green.';
|
|
387
|
+
if (md && md.failing_tests) {
|
|
388
|
+
return ` ci-land: the PR is RED — ${md.failing_tests}. Reproduce with \`node tests/<name>.mjs\`, ${fix}`;
|
|
389
|
+
}
|
|
390
|
+
if (reason === 'failing_check_unreadable') {
|
|
391
|
+
return ' ci-land: the PR is RED, and this instance cannot see which check failed (the GitHub App lacks '
|
|
392
|
+
+ `\`Checks: read\` — an owner grant, not a fault in your work). Run \`npm test\` locally to find it, ${fix}`;
|
|
393
|
+
}
|
|
394
|
+
const named = /^(?:non_required_check_failing|failing_check):(.+)$/.exec(reason);
|
|
395
|
+
return named ? ` ci-land: the PR is RED — the \`${named[1]}\` check failed; ${fix}` : null;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// redPrLines — the red line followed by the same reason in plain words (task 1003989).
|
|
399
|
+
// The card is keyed on the merge reason; when the failing tests were readable that
|
|
400
|
+
// reason is `failing_check:<name>`, which resolves to the failing_check card.
|
|
401
|
+
// task 1003764: the merge trap sits between them. `opts` = { taskId, via } for its wording.
|
|
402
|
+
function redPrLines(md, opts = {}) {
|
|
403
|
+
const red = redPrLine(md);
|
|
404
|
+
if (red && md.not_started) return [red, ...notStartedLines(md), ...plainCardLines('ci_not_started')];
|
|
405
|
+
return red ? [red, ...mergeTrapLines(md, opts), ...plainCardLines((md && md.reason) || 'failing_check')] : [];
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// notStartedLines — task 1004289. What to do when CI never ran, instead of the merge trap
|
|
409
|
+
// (there is no failure to reproduce). Re-running is the remedy, not re-pushing: the same
|
|
410
|
+
// commit is fine, it simply was never tested. Pure + exported.
|
|
411
|
+
function notStartedLines(md) {
|
|
412
|
+
const rerun = md && /^\d+$/.test(String(md.run_id || '')) ? `\`gh run rerun ${md.run_id} --failed\`` : '"Re-run failed jobs" on the PR';
|
|
413
|
+
return [
|
|
414
|
+
' ci-land: this is the repo OWNER\'s to fix, on GitHub: the account\'s Actions budget / spending limit or payment method.',
|
|
415
|
+
` ci-land: once Actions can run again, ${rerun} starts the checks on the SAME commit — do not re-push or edit the work.`,
|
|
416
|
+
];
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// The unit tests that gate GENERATED files — each compares a committed artifact with a
|
|
420
|
+
// fresh build of it. `fitness` holds the combined gate (fitness.js "generated artifacts
|
|
421
|
+
// fresh": copy registry, API docs, file map, nested CLAUDE.md blocks, the §13 snippet).
|
|
422
|
+
// tests/ship_land_red_pr.mjs fails if one of these names stops being a real test file.
|
|
423
|
+
const FRESHNESS_TESTS = new Set(['fitness', 'api_docs', 'api_client', 'file_map', 'repo_map', 'session_index', 'interaction_posture']);
|
|
424
|
+
|
|
425
|
+
// failingTestNames — "2 failed: a, b" (the unit-report line, run-unit-tests.js
|
|
426
|
+
// describeFailures) → ['a', 'b']. A line cut at the status limit ends in '…'; the cut
|
|
427
|
+
// name is dropped rather than guessed at. Pure.
|
|
428
|
+
function failingTestNames(text) {
|
|
429
|
+
const m = /^\s*\d+\s+failed:\s*(.*)$/.exec(String(text || ''));
|
|
430
|
+
if (!m) return [];
|
|
431
|
+
const names = m[1].split(',').map((s) => s.trim()).filter(Boolean);
|
|
432
|
+
if (names.length && names[names.length - 1].endsWith('…')) names.pop();
|
|
433
|
+
return names;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// mergeTrapLines — task 1003764. CI tests the MERGE, not the branch: a pull_request run
|
|
437
|
+
// checks out the PR merged into the CURRENT main, so a branch that was green when pushed
|
|
438
|
+
// goes red when main moves under it, and re-running the test on the branch shows nothing
|
|
439
|
+
// wrong. Task 1003747's land sat "waiting" for ~20 minutes of git archaeology on exactly
|
|
440
|
+
// that — main moved six commits, the copy registry went stale in the merged tree only.
|
|
441
|
+
// Every red PR gets the trap named; a failing freshness gate also gets its healing command,
|
|
442
|
+
// which differs by push path (a credential-less machine cannot merge main locally, and the
|
|
443
|
+
// server heals it for them — publish-reconciler refreshStaleGenerated). Pure + exported.
|
|
444
|
+
function mergeTrapLines(md, { taskId = '<id>', via = 'local' } = {}) {
|
|
445
|
+
const lines = [
|
|
446
|
+
' ci-land: CI tests your branch MERGED with the current main, not the branch alone — if the failure',
|
|
447
|
+
via === 'server'
|
|
448
|
+
? ' does not reproduce on your branch, main moved under the PR after it was pushed.'
|
|
449
|
+
: ' does not reproduce on your branch, main moved under it: `git fetch origin && git merge origin/main`, then re-run it.',
|
|
450
|
+
];
|
|
451
|
+
const gates = failingTestNames(md && md.failing_tests).filter((n) => FRESHNESS_TESTS.has(n));
|
|
452
|
+
if (!gates.length) return lines;
|
|
453
|
+
const named = gates.map((g) => `\`${g}\``).join(', ');
|
|
454
|
+
lines.push(` ci-land: ${named} ${gates.length > 1 ? 'are freshness gates' : 'is a freshness gate'}, so "fix it" here means regenerate: a generated file (copy`);
|
|
455
|
+
lines.push(' registry, API docs, repo map…) is stale in the MERGED tree even though your branch was fresh.');
|
|
456
|
+
if (via === 'server') {
|
|
457
|
+
lines.push(' The server regenerates stale generated files on the merged tree itself (every ~5 min, up to 3 tries),');
|
|
458
|
+
lines.push(' so this usually clears without you; if it stays red the server flags the task needs_rebase.');
|
|
459
|
+
} else {
|
|
460
|
+
lines.push(` Heal it: \`git fetch origin && git merge origin/main\`, then re-run \`node scripts/bongos/ship.js ${taskId}\` — the ship`);
|
|
461
|
+
lines.push(' regenerates every generated file on the merged tree before it pushes (`node scripts/bongos/ship-check.js` shows which).');
|
|
462
|
+
}
|
|
463
|
+
lines.push(' A busy main can re-stale it while CI re-runs; a repeat is that race, not a new fault.');
|
|
464
|
+
return lines;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// redBlocksMerge — is this red the kind that stops the merge? A failing REQUIRED check
|
|
468
|
+
// (`failing_check…`) does; a failing optional one does not (GitHub still merges an UNSTABLE
|
|
469
|
+
// PR), so only the first may turn the closing banner red (task 1003764). Pure + exported.
|
|
470
|
+
function redBlocksMerge(md) {
|
|
471
|
+
return /^failing_check/.test(String((md && md.reason) || ''));
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// A check conclusion (CheckRun) or state (status context) that means FAILED. Pending and
|
|
475
|
+
// expected are waiting, not red — reporting them as failures would be the mirror image of
|
|
476
|
+
// the bug this names (a failure dressed as waiting).
|
|
477
|
+
// The set itself lives in check-rollup.js, shared with the server's mergeBlockReason (task 1004666).
|
|
478
|
+
|
|
479
|
+
// localMergeDriver — task 1003764. The laptop path watches its PR with the builder's own
|
|
480
|
+
// gh, and read only state + mergeCommit, so a red required check was invisible for the
|
|
481
|
+
// whole wait. This reads `gh pr view --json statusCheckRollup,mergeStateStatus,headRefOid`
|
|
482
|
+
// through the server's parser and answers in publish-status's merge_driver shape, so both
|
|
483
|
+
// poll paths hand redPrLines the same thing. `failingTestsFor(sha)` reads the unit-report
|
|
484
|
+
// status (gh pr view omits a status's description) and is asked only once that status is
|
|
485
|
+
// itself red, i.e. posted. Null when nothing is red. Pure + exported.
|
|
486
|
+
// task 1004289 — `neverStarted(rawCheck)` answers "did this red job never run at all?"
|
|
487
|
+
// (jobNeverStarted below). When EVERY red check is one, nothing was tested, and the
|
|
488
|
+
// answer is { reason: 'ci_not_started:<name>', not_started: true, run_id } rather than
|
|
489
|
+
// a failing check the builder is told to fix.
|
|
490
|
+
function localMergeDriver(pr, failingTestsFor = () => null, neverStarted = () => false) {
|
|
491
|
+
if (!pr || pr.state !== 'OPEN' || !Array.isArray(pr.statusCheckRollup)) return null;
|
|
492
|
+
const { checks } = readCheckRollup({ contexts: { nodes: pr.statusCheckRollup } });
|
|
493
|
+
const red = checks.filter((c) => RED_CONCLUSIONS.has(String(c.conclusion || '').toUpperCase()));
|
|
494
|
+
if (!red.length) return null;
|
|
495
|
+
const redRaw = pr.statusCheckRollup.filter((c) => c && RED_CONCLUSIONS.has(String(c.conclusion || c.state || '').toUpperCase()));
|
|
496
|
+
if (redRaw.length && redRaw.every((c) => neverStarted(c))) {
|
|
497
|
+
const run = /\/runs\/(\d+)\//.exec(String(redRaw[0].detailsUrl || ''));
|
|
498
|
+
return { reason: `ci_not_started:${red[0].name}`, not_started: true, failing_tests: null, run_id: run ? run[1] : null };
|
|
499
|
+
}
|
|
500
|
+
const kind = pr.mergeStateStatus === 'UNSTABLE' ? 'non_required_check_failing' : 'failing_check';
|
|
501
|
+
const reported = red.some((c) => c.name === UNIT_REPORT_CONTEXT);
|
|
502
|
+
return { reason: `${kind}:${red[0].name}`, failing_tests: (reported && failingTestsFor(pr.headRefOid)) || null };
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// jobNeverStarted — task 1004289. When the account cannot run Actions (its budget is
|
|
506
|
+
// spent, or a payment failed), GitHub still marks every job FAILED seconds after it was
|
|
507
|
+
// queued, with no steps and no runner, and one annotation saying why: "The job was not
|
|
508
|
+
// started because an Actions budget is preventing further use." (PR 1211, 2026-09-25).
|
|
509
|
+
// Read as an ordinary red check, that told the builder to fix their code — advice that
|
|
510
|
+
// cannot help, where each retry is another failed run. An Actions job's id (the tail of
|
|
511
|
+
// its detailsUrl) is its check-run id, so its annotations are one read away. FAIL-OPEN:
|
|
512
|
+
// anything unreadable is "no", which keeps the ordinary red wording. `gh` is injectable.
|
|
513
|
+
const NOT_STARTED_RE = /^\s*The job was not started because\b/i;
|
|
514
|
+
function jobNeverStarted(check, gh = ghJson) {
|
|
515
|
+
if (!check || (check.__typename && check.__typename !== 'CheckRun')) return false;
|
|
516
|
+
const m = /\/job\/(\d+)(?:[/?#]|$)/.exec(String(check.detailsUrl || ''));
|
|
517
|
+
if (!m) return false;
|
|
518
|
+
const notes = gh(['api', `repos/{owner}/{repo}/check-runs/${m[1]}/annotations`]);
|
|
519
|
+
return Array.isArray(notes) && notes.some((a) => a && NOT_STARTED_RE.test(String(a.message || '')));
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// unitReportFor — the failing-test line the `unit` workflow posted on `sha`, read with this
|
|
523
|
+
// machine's gh through the same parser the server uses. Null when unreadable; the red line
|
|
524
|
+
// then names the check instead, as it did before the report existed. `gh` is injectable.
|
|
525
|
+
function unitReportFor(sha, gh = ghJson) {
|
|
526
|
+
if (!/^[0-9a-f]{7,64}$/i.test(String(sha || ''))) return null;
|
|
527
|
+
const combined = gh(['api', `repos/{owner}/{repo}/commits/${sha}/status`]);
|
|
528
|
+
const nodes = ((combined && combined.statuses) || []).map((s) => ({ ...s, __typename: 'StatusContext' }));
|
|
529
|
+
return readCheckRollup({ contexts: { nodes } }).failing_tests;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// task 1003499 — a CONFLICTING PR is a land that cannot happen, however green it is.
|
|
533
|
+
// GitHub's auto-merge waits for a clean merge as well as for green checks, so a PR
|
|
534
|
+
// whose branch conflicts with main sits open under a fully green rollup and never
|
|
535
|
+
// merges. PR #497 sat like that for ~25 minutes while both polls below said nothing
|
|
536
|
+
// and then printed "auto-merge is armed ... NOT a failure", the banner a land that IS
|
|
537
|
+
// on its way gets. The server already knew (mergeBlockReason -> 'merge_conflict'); the
|
|
538
|
+
// ship never asked. Pure + exported. Takes both shapes it is handed: `gh pr view`'s
|
|
539
|
+
// camelCase (mergeable, mergeStateStatus) and publish-status's snake_case merge_driver
|
|
540
|
+
// (mergeable, merge_state, reason). A read that failed (null) is not a conflict.
|
|
541
|
+
function prConflicting(pr) {
|
|
542
|
+
if (!pr) return false;
|
|
543
|
+
const state = pr.mergeStateStatus ?? pr.merge_state;
|
|
544
|
+
return pr.mergeable === 'CONFLICTING' || state === 'DIRTY' || pr.reason === 'merge_conflict';
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// What the poll says the moment it sees the conflict. Pure + exported so the wording
|
|
548
|
+
// is pinned by tests/ship_land_conflict.mjs. The poll keeps waiting afterwards on
|
|
549
|
+
// purpose: a conflict only in generated files is healed by the server's own resolver
|
|
550
|
+
// on its next sweep (ADR 0082), and the PR then merges inside this same window.
|
|
551
|
+
function conflictPrLines(taskId) {
|
|
552
|
+
return [
|
|
553
|
+
' ci-land: the PR CONFLICTS with main, so auto-merge cannot fire until that is resolved, however green its checks are.',
|
|
554
|
+
' ci-land: a conflict only in generated files is healed by the server on its next sweep (~5 min), so this keeps waiting.',
|
|
555
|
+
' ci-land: anything hand-written waits for you. From this worktree:',
|
|
556
|
+
' git fetch -q origin && git merge origin/main # resolve the conflicts, commit',
|
|
557
|
+
` node scripts/bongos/ship.js ${taskId} # resumes the land; it does not re-grade`,
|
|
558
|
+
...plainCardLines('merge_conflict'),
|
|
559
|
+
];
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// noteConflict — one poll's worth of conflict tracking, shared by both loops. Prints
|
|
563
|
+
// the lines above when the PR BECOMES conflicting (not on every 10s poll, and once
|
|
564
|
+
// more if main moves on and undoes a heal), and returns whether it conflicts now.
|
|
565
|
+
// A failed read keeps the last answer rather than inventing a new one.
|
|
566
|
+
function noteConflict(taskId, pr, wasConflicting) {
|
|
567
|
+
if (!pr) return wasConflicting;
|
|
568
|
+
const now = prConflicting(pr);
|
|
569
|
+
if (now && !wasConflicting) for (const line of conflictPrLines(taskId)) console.log(line);
|
|
570
|
+
return now;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// landConflicted — the verdict when the wait ends with the PR STILL conflicting. It is
|
|
574
|
+
// not landing on its own, so it must not print the "landing automatically" banner or
|
|
575
|
+
// the land_pending card ("Nothing to do. This is normal, not a failure."): task
|
|
576
|
+
// 1002541's rule that a land which is not happening must not announce itself as
|
|
577
|
+
// success. No bailId, so ship-merge never reroutes it: the PR already exists and is
|
|
578
|
+
// the problem. /strand-fix walks the cure (its case C: merge main in, resolve, re-ship).
|
|
579
|
+
function landConflicted(taskId) {
|
|
580
|
+
console.log('');
|
|
581
|
+
console.log(` ci-land: still CONFLICTING when the wait ended, so this will NOT land on its own. The task stays at 'confirmed' until the conflict is resolved (/strand-fix ${taskId} walks it).`);
|
|
582
|
+
return landBailed('the PR conflicts with main, so it cannot merge until the conflict is resolved', `/strand-fix ${taskId}`);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// One module-scope sleep command shared by both poll loops (task 1093 / C9). A
|
|
586
|
+
// child `node -e setTimeout` is used (not `await new Promise`) so it blocks
|
|
587
|
+
// identically in the SYNCHRONOUS pollCiDeploy and the async pollServerPublish —
|
|
588
|
+
// the loops keep their own structure (sync vs async, 1-stage vs 2-stage); only
|
|
589
|
+
// the ~10s cadence is shared.
|
|
590
|
+
const POLL_SLEEP_CMD = 'node -e "setTimeout(()=>{}, 10000)"';
|
|
591
|
+
|
|
592
|
+
// pollServerPublish — the server-mediated analogue of pollCiDeploy. Polls the
|
|
593
|
+
// GDS publish-status endpoint (which the server answers from GitHub, and which
|
|
594
|
+
// reconciles the task to shipped when it observes merge+deploy — task 1049) until
|
|
595
|
+
// the PR merges + deploy-prod succeeds. Returns true when prod is confirmed live;
|
|
596
|
+
// a timeout with an armed PR is success-PENDING (the publish worked), not failure.
|
|
597
|
+
// A timeout with a CONFLICTING PR is not (task 1003499): see landConflicted.
|
|
598
|
+
// `deps` exists for tests/ship_land_conflict.mjs; a real ship passes none.
|
|
599
|
+
async function pollServerPublish(taskId, branch, deps = {}) {
|
|
600
|
+
const TRIES = 54; // ~9 min at 10s — checks + auto-merge + Actions deploy
|
|
601
|
+
const readStatus = deps.readStatus || (async (q) => (await cliClient()).tasks.getTasksIdPublishStatus(q));
|
|
602
|
+
const pause = deps.pause || (() => shellOk(POLL_SLEEP_CMD));
|
|
603
|
+
console.log(' ci-land: waiting for auto-merge + prod deploy (polling the server)...');
|
|
604
|
+
// task 1002645: GitHub can report merged+deployed while the SERVER refused the
|
|
605
|
+
// confirmed→shipped flip (reconcile_blocked — the task-1547 land proof missed).
|
|
606
|
+
// "Prod is live" + exit here was a lie that left the task stranded with no
|
|
607
|
+
// signal. Say the real reason and keep polling — attest-gate now records the
|
|
608
|
+
// pushed tip, so the proof usually heals within the window.
|
|
609
|
+
let blockedReason = null;
|
|
610
|
+
let redLine = null;
|
|
611
|
+
let conflicting = false;
|
|
612
|
+
let stuckRed = false; // task 1003764: a failing required check on the LAST read turns the closing banner red
|
|
613
|
+
let readFailure = null;
|
|
614
|
+
for (let i = 0; i < TRIES; i++) {
|
|
615
|
+
const r = await readStatus({ id: taskId, query: { branch } });
|
|
616
|
+
if (!r.ok) {
|
|
617
|
+
// task 1003764: a failed status read used to be skipped in silence, so a broken
|
|
618
|
+
// diagnostic looked exactly like slow CI. Say so once per distinct failure.
|
|
619
|
+
const { code } = normalizeApiError(r.data);
|
|
620
|
+
const why = `HTTP ${r.status}${code ? ` ${code}` : ''}`;
|
|
621
|
+
if (why !== readFailure) {
|
|
622
|
+
readFailure = why;
|
|
623
|
+
console.log(` ci-land: could not read the land status from the server (${why}) — still polling.`);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
if (r.ok && r.data) {
|
|
627
|
+
const red = redPrLine(r.data.merge_driver);
|
|
628
|
+
if (red && red !== redLine) {
|
|
629
|
+
redLine = red;
|
|
630
|
+
for (const line of redPrLines(r.data.merge_driver, { taskId, via: 'server' })) console.log(line);
|
|
631
|
+
}
|
|
632
|
+
stuckRed = !!red && redBlocksMerge(r.data.merge_driver);
|
|
633
|
+
conflicting = noteConflict(taskId, r.data.merge_driver, conflicting);
|
|
634
|
+
const outcome = classifyLandOutcome(r.data);
|
|
635
|
+
if (outcome === 'shipped') {
|
|
636
|
+
if (r.data.reconcile_blocked) {
|
|
637
|
+
if (r.data.reconcile_blocked !== blockedReason) {
|
|
638
|
+
blockedReason = r.data.reconcile_blocked;
|
|
639
|
+
console.log(` ci-land: merged, but the server did NOT flip the task to shipped: ${blockedReason}. Still polling (the reconciler retries every sweep)...`);
|
|
640
|
+
}
|
|
641
|
+
} else {
|
|
642
|
+
console.log(` ci-land: merged (${String(r.data.merge_sha || '').slice(0, 8)}) + deploy-prod succeeded. Prod is live.`);
|
|
643
|
+
return landed();
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
if (outcome === 'failed') {
|
|
647
|
+
console.log(` ci-land: PR was CLOSED without merging (a required check failed, or it was closed manually). Fix it and re-run \`node scripts/bongos/ship.js ${taskId}\` to resume. Task stays at 'confirmed'.`);
|
|
648
|
+
return landBailed('the PR was closed without merging (a check failed, or it was closed manually)', `node scripts/bongos/ship.js ${taskId}`);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
pause();
|
|
652
|
+
}
|
|
653
|
+
if (blockedReason) {
|
|
654
|
+
console.log('');
|
|
655
|
+
for (const line of reconcileBlockedLines(taskId, blockedReason)) console.log(line);
|
|
656
|
+
for (const line of plainCardLines('reconcile_blocked')) console.log(line);
|
|
657
|
+
return landBailed(`the PR merged but the server could not prove the land is this task's: ${blockedReason}`, `node scripts/bongos/ship.js ${taskId}`);
|
|
658
|
+
}
|
|
659
|
+
if (conflicting) return landConflicted(taskId);
|
|
660
|
+
printLandPending(taskId, { red: stuckRed });
|
|
661
|
+
return landPending();
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
// attestGateTrust — task 1169 (ADR 0058). Ask the SERVER to post the trustless
|
|
665
|
+
// gate-author-trust commit status for THIS builder's server-resolved rank on the
|
|
666
|
+
// pushed head SHA. ship.js's local path pushes + opens the PR with the laptop's
|
|
667
|
+
// OWN gh credential, but only the server can forge the rank attestation the
|
|
668
|
+
// ENFORCING gate-review check reads — without it a Metic+ author's gate-surface PR
|
|
669
|
+
// from a laptop is BLOCKED and they can't self-approve it (task 1162 / PR #131).
|
|
670
|
+
// Best-effort + never throws: a non-Metic author, an unconfigured server, or a
|
|
671
|
+
// transient failure just leaves the PR un-attested → it escalates (the safe
|
|
672
|
+
// direction). A non-gate PR is unaffected by the attestation either way.
|
|
673
|
+
//
|
|
674
|
+
// task 1004055 — the endpoint does TWO things, and only one of them was ever
|
|
675
|
+
// reported. Besides the attestation (best-effort, and declining is a legitimate
|
|
676
|
+
// answer) it records claims.published_head_sha, the tip that makes the ship
|
|
677
|
+
// PROVABLE — and that half is load-bearing, not best-effort: without it POST /ship
|
|
678
|
+
// refuses the confirmed→shipped flip. So this returns { recorded, attested, reason }
|
|
679
|
+
// rather than undefined, and callers act on `recorded`. It still never throws.
|
|
680
|
+
async function attestGateTrust(taskId, headSha) {
|
|
681
|
+
if (!headSha) return { recorded: false, attested: false, reason: 'no head SHA to attest' };
|
|
682
|
+
let r;
|
|
683
|
+
try {
|
|
684
|
+
r = await (await cliClient()).tasks.postTasksIdAttestGate({ id: taskId, body: { head_sha: headSha } });
|
|
685
|
+
} catch (e) {
|
|
686
|
+
// task 1004055: a bare `catch (_) {}` here meant a thrown request error left NO
|
|
687
|
+
// trace at all — the quietest of the failure shapes, and the one that reached
|
|
688
|
+
// the builder as an unexplained ship_land_not_proven.
|
|
689
|
+
console.log(` ci-land: gate attestation request failed (${(e && e.message) || 'unknown error'}).`);
|
|
690
|
+
return { recorded: false, attested: false, reason: `request failed (${(e && e.message) || 'unknown error'})` };
|
|
691
|
+
}
|
|
692
|
+
const recorded = landProofRecorded(r);
|
|
693
|
+
if (r.ok && r.data) {
|
|
694
|
+
if (r.data.attested) {
|
|
695
|
+
console.log(' ci-land: gate-author-trust attested on the head SHA (Metic+) — a gate-surface PR auto-passes the ADR-0058 gatekeeper.');
|
|
696
|
+
} else {
|
|
697
|
+
console.log(` ci-land: gate-author-trust NOT attested (${r.data.reason || 'rank below Metic'}) — a gate-surface PR will need owner approval; a non-gate PR is unaffected.`);
|
|
698
|
+
}
|
|
699
|
+
return { recorded, attested: !!r.data.attested, reason: r.data.reason || null };
|
|
700
|
+
}
|
|
701
|
+
if (r.status === 503) {
|
|
702
|
+
console.log(' ci-land: the server has no push credential to post the gate attestation (operator: GITHUB_APP_* / GITHUB_PUSH_TOKEN). A gate-surface PR will need owner approval.');
|
|
703
|
+
return { recorded, attested: false, reason: 'the server has no push credential' };
|
|
704
|
+
}
|
|
705
|
+
console.log(` ci-land: gate attestation request failed (HTTP ${r.status}); a gate-surface PR may need a manual re-run / owner approval.`);
|
|
706
|
+
return { recorded, attested: false, reason: `HTTP ${r.status}` };
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// landProofRecorded — PURE. Did an attest-gate response actually record
|
|
710
|
+
// claims.published_head_sha (task 1004055)? That row is the durable per-task land
|
|
711
|
+
// proof; without it POST /tasks/:id/ship refuses with ship_land_not_proven and the
|
|
712
|
+
// task strands at 'confirmed' with its work already on main.
|
|
713
|
+
//
|
|
714
|
+
// The server SAYS so in `tip_recorded` — on the 200 body and in the 503's details,
|
|
715
|
+
// because the write deliberately sits BEFORE the credential check. Prefer that.
|
|
716
|
+
// A server that predates the field sends neither, which is the NORMAL state here:
|
|
717
|
+
// an instance runs a PINNED core, so it lags main by however long the pin sits
|
|
718
|
+
// still. For those, fall back to the route's contract — the write is above the
|
|
719
|
+
// credential 503, so 200 and 503 both mean the tip landed and nothing else does.
|
|
720
|
+
// Exported so the truth table is pinned with no server.
|
|
721
|
+
function landProofRecorded(r) {
|
|
722
|
+
if (!r || typeof r.status !== 'number') return false;
|
|
723
|
+
const body = r.data || {};
|
|
724
|
+
const explicit = body.tip_recorded !== undefined
|
|
725
|
+
? body.tip_recorded
|
|
726
|
+
: (body.error && body.error.details ? body.error.details.tip_recorded : undefined);
|
|
727
|
+
if (explicit !== undefined) return explicit === true;
|
|
728
|
+
return r.status === 200 || r.status === 503;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// landProofWarningLines — PURE. What to print when the proof did NOT get recorded
|
|
732
|
+
// (task 1004055). Without it POST /ship refuses, the task parks at 'confirmed' —
|
|
733
|
+
// which gates the builder's WHOLE queue — and the publish-reconciler eventually
|
|
734
|
+
// writes strand:land_not_proven, after which nothing heals it. Say it HERE, while
|
|
735
|
+
// the sha is still on screen, and hand over the calls that fix it, rather than
|
|
736
|
+
// letting it surface as an opaque 409 later.
|
|
737
|
+
//
|
|
738
|
+
// `merged` is the tense, and it is the whole difference between the two callers:
|
|
739
|
+
// the local-merge path has ALREADY put the work on main and needs the full
|
|
740
|
+
// two-call recovery now; the PR path has only pushed, so the land may still be
|
|
741
|
+
// minutes away and the same recovery would be premature. Exported so both
|
|
742
|
+
// wordings are pinned.
|
|
743
|
+
function landProofWarningLines(taskId, sha, reason, { merged = true } = {}) {
|
|
744
|
+
const head = sha || '<the merge commit on main>';
|
|
745
|
+
const why = ` WARNING: the land proof for task ${taskId} was NOT recorded (${reason || 'unknown'}).`;
|
|
746
|
+
const fix = ` node scripts/bongos/api.js POST /tasks/${taskId}/attest-gate --body '{"head_sha":"${head}"}'`;
|
|
747
|
+
if (!merged) {
|
|
748
|
+
return [
|
|
749
|
+
'',
|
|
750
|
+
why,
|
|
751
|
+
' Nothing is lost yet — the branch is pushed and the PR still lands normally.',
|
|
752
|
+
' But if the ship then refuses with ship_land_not_proven, re-record the tip',
|
|
753
|
+
' against the merge commit and re-run the ship:',
|
|
754
|
+
` node scripts/bongos/api.js POST /tasks/${taskId}/attest-gate --body '{"head_sha":"<the merge commit on main>"}'`,
|
|
755
|
+
` node scripts/bongos/ship.js ${taskId}`,
|
|
756
|
+
];
|
|
757
|
+
}
|
|
758
|
+
return [
|
|
759
|
+
'',
|
|
760
|
+
why,
|
|
761
|
+
' The merge IS on main, but the server cannot prove the land is this task\'s, so',
|
|
762
|
+
' the confirmed -> shipped flip will be refused (ship_land_not_proven) and the',
|
|
763
|
+
' task will park at confirmed — which blocks every new claim you make. Fix it:',
|
|
764
|
+
fix,
|
|
765
|
+
` node scripts/bongos/api.js POST /tasks/${taskId}/ship --body '{}'`,
|
|
766
|
+
];
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// pickStaleGateReviewRun — PURE. Among `gh run list --json
|
|
770
|
+
// databaseId,headSha,status,conclusion` results for the gate-review workflow,
|
|
771
|
+
// find a run on THIS head SHA that has already COMPLETED without success — the
|
|
772
|
+
// one to re-run after the attestation is posted, because a new commit status does
|
|
773
|
+
// NOT re-trigger a pull_request-triggered check (the task 1162 / PR #131 gotcha).
|
|
774
|
+
// Returns the run's databaseId, or null when there's nothing stale to re-run (no
|
|
775
|
+
// run yet, still in flight, or already green). Exported for unit tests.
|
|
776
|
+
function pickStaleGateReviewRun(runs, headSha) {
|
|
777
|
+
if (!headSha || !Array.isArray(runs)) return null;
|
|
778
|
+
const hit = runs.find(
|
|
779
|
+
(r) => r && r.headSha === headSha && r.status === 'completed' && r.conclusion && r.conclusion !== 'success'
|
|
780
|
+
);
|
|
781
|
+
return hit ? (hit.databaseId ?? null) : null;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
// rerunGateReviewIfStale — best-effort gh re-run of a stale (completed-non-success)
|
|
785
|
+
// gate-review run on the current head, so it re-reads the freshly-posted
|
|
786
|
+
// gate-author-trust attestation. Only acts when such a run exists: a freshly-opened
|
|
787
|
+
// PR needs NO nudge (gate-review runs once, AFTER the attestation, and passes); the
|
|
788
|
+
// SHA-reuse-after-red resume case (and the rare push-then-attest race) needs one.
|
|
789
|
+
function rerunGateReviewIfStale(branch, headSha) {
|
|
790
|
+
const runs = ghJson([
|
|
791
|
+
'run', 'list', '--workflow', 'gate-review.yml', '--branch', branch,
|
|
792
|
+
'--json', 'databaseId,headSha,status,conclusion', '--limit', '15',
|
|
793
|
+
]);
|
|
794
|
+
const id = pickStaleGateReviewRun(runs, headSha);
|
|
795
|
+
if (id == null) return false;
|
|
796
|
+
console.log(` ci-land: re-running the stale gate-review check (run ${id}) so it re-reads the gate-author-trust attestation...`);
|
|
797
|
+
return ghArgvOk(['run', 'rerun', String(id)]);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
// ---------- why the push failed, and whether retrying can ever help ----------
|
|
801
|
+
//
|
|
802
|
+
// A failed `git push` already parks the task at `confirmed` and opens no PR,
|
|
803
|
+
// which is correct. What was wrong (task 1003293) was the ADVICE: "Fix the push
|
|
804
|
+
// and re-ship" is useless for the most common cause, because re-shipping fails
|
|
805
|
+
// identically every time and the reconciler cannot heal a branch that was never
|
|
806
|
+
// pushed. The task then sits at `confirmed` with its code on one laptop, looking
|
|
807
|
+
// like an ordinary pending land. That happened twice in one session — both times
|
|
808
|
+
// on a commit touching .github/workflows/, both times invisible until someone
|
|
809
|
+
// checked git instead of the log.
|
|
810
|
+
//
|
|
811
|
+
// So the distinction that matters is TERMINAL vs transient. A terminal failure
|
|
812
|
+
// must name the actual remedy; a transient one may honestly say "re-ship".
|
|
813
|
+
// `argvOk` runs the push with stdio:'inherit', so git's own message reaches the
|
|
814
|
+
// log but nothing ever reads it — these patterns read it.
|
|
815
|
+
const PUSH_DIAGNOSES = [
|
|
816
|
+
{
|
|
817
|
+
id: 'workflow_scope',
|
|
818
|
+
// GitHub's wording: "refusing to allow an OAuth App to create or update
|
|
819
|
+
// workflow `.github/workflows/x.yml` without `workflow` scope".
|
|
820
|
+
match: /without .{0,3}workflow.{0,3} scope|refusing to allow (?:an?|the) \S+ (?:App|integration)/i,
|
|
821
|
+
terminal: true,
|
|
822
|
+
why: 'this branch changes a file under .github/workflows/, and the credential git used has no `workflow` scope — GitHub refuses that push regardless of how often it is retried',
|
|
823
|
+
fix: 'push over SSH once, then re-run the ship:\n git push git@github.com:<owner>/<repo>.git <branch>\n (or re-authenticate the CLI with the `workflow` scope: gh auth refresh -h github.com -s workflow)',
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
id: 'protected_branch',
|
|
827
|
+
match: /GH006|protected branch|required status check/i,
|
|
828
|
+
terminal: true,
|
|
829
|
+
why: 'branch protection refused the push outright',
|
|
830
|
+
fix: 'land through a pull request instead of pushing directly, or have an admin adjust the rule',
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
id: 'auth',
|
|
834
|
+
match: /Authentication failed|could not read Username|Permission denied \(publickey\)|remote: Invalid username or password|403 Forbidden/i,
|
|
835
|
+
terminal: true,
|
|
836
|
+
why: 'git could not authenticate to the remote at all',
|
|
837
|
+
fix: 'restore the credential (gh auth login, or an SSH key the remote accepts), then re-run the ship',
|
|
838
|
+
},
|
|
839
|
+
{
|
|
840
|
+
id: 'stale_branch',
|
|
841
|
+
match: /non-fast-forward|fetch first|behind its remote counterpart|Updates were rejected/i,
|
|
842
|
+
terminal: false,
|
|
843
|
+
why: 'the remote branch has commits this checkout does not',
|
|
844
|
+
fix: 'git fetch && git rebase origin/<branch>, then re-run the ship',
|
|
845
|
+
},
|
|
846
|
+
];
|
|
847
|
+
|
|
848
|
+
// Pure: classify a failed push from git's stderr. Exported + tested.
|
|
849
|
+
// An unrecognised failure is reported as NON-terminal on purpose — "try again"
|
|
850
|
+
// is the safe default when we do not know, and a wrong "this can never work"
|
|
851
|
+
// would send someone hunting a problem that does not exist.
|
|
852
|
+
function pushDiagnosis(stderr) {
|
|
853
|
+
const text = String(stderr == null ? '' : stderr);
|
|
854
|
+
for (const d of PUSH_DIAGNOSES) {
|
|
855
|
+
if (d.match.test(text)) return { id: d.id, terminal: d.terminal, why: d.why, fix: d.fix };
|
|
856
|
+
}
|
|
857
|
+
return { id: 'unknown', terminal: false, why: 'the push failed for a reason this lane does not recognise', fix: 'read git\'s message above, resolve it, then re-run the ship' };
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
// Push, capturing stderr so it can be diagnosed — and echoing it so the log still
|
|
861
|
+
// shows exactly what git said, which stdio:'inherit' gave us for free.
|
|
862
|
+
function pushCapturing(branch, deps = {}) {
|
|
863
|
+
const exec = deps.execFileSync || require('node:child_process').execFileSync;
|
|
864
|
+
try {
|
|
865
|
+
exec('git', ['push', 'origin', branch], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
866
|
+
return { ok: true, stderr: '' };
|
|
867
|
+
} catch (e) {
|
|
868
|
+
const stderr = [e && e.stderr, e && e.stdout].filter(Boolean).join('\n');
|
|
869
|
+
if (stderr) process.stderr.write(stderr.endsWith('\n') ? stderr : `${stderr}\n`);
|
|
870
|
+
return { ok: false, stderr };
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// ciLandLocal — today's local path: this machine pushes the branch + opens the PR
|
|
875
|
+
// + enables auto-merge via git + gh. async since task 1169 — it asks the server to
|
|
876
|
+
// post the gate-author-trust attestation between the push and the PR open.
|
|
877
|
+
async function ciLandLocal(taskId, branch, valueSummary, { hold = false } = {}) {
|
|
878
|
+
const headSha = gitOk('git rev-parse HEAD');
|
|
879
|
+
|
|
880
|
+
console.log(` pushing ${branch} to origin...`);
|
|
881
|
+
const pushed = pushCapturing(branch);
|
|
882
|
+
if (!pushed.ok) {
|
|
883
|
+
const d = pushDiagnosis(pushed.stderr);
|
|
884
|
+
console.log(` ci-land: push FAILED — ${d.why}.`);
|
|
885
|
+
console.log(` ci-land: nothing was pushed and no PR exists; task stays at confirmed.`);
|
|
886
|
+
if (d.terminal) {
|
|
887
|
+
// The important line. Re-shipping cannot fix this, and the reconciler
|
|
888
|
+
// cannot heal a branch that never reached the remote — so do not say
|
|
889
|
+
// "re-ship" and leave the work stranded on one machine.
|
|
890
|
+
console.log(' ci-land: RE-SHIPPING WILL FAIL THE SAME WAY. Do this instead:');
|
|
891
|
+
console.log(` ${d.fix}`);
|
|
892
|
+
} else {
|
|
893
|
+
console.log(` ci-land: to retry — ${d.fix}`);
|
|
894
|
+
}
|
|
895
|
+
for (const line of plainCardLines(`ship:${d.id}`)) console.log(line);
|
|
896
|
+
return landBailed(
|
|
897
|
+
`could not push ${branch} to origin (${d.id})`,
|
|
898
|
+
d.terminal ? d.fix.split('\n')[0] : `node scripts/bongos/ship.js ${taskId}`,
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// task 1169 (ADR 0058): attest the author's trust tier on the head SHA BEFORE
|
|
903
|
+
// opening the PR, so the gate-review check reads it on its first (and only) run
|
|
904
|
+
// and a Metic+ gate-surface PR auto-passes — race-free for a fresh PR, since the
|
|
905
|
+
// `gh pr create` below is what fires gate-review and it runs only after this
|
|
906
|
+
// returns. (A reused open PR is handled by the re-run nudge after auto-merge.)
|
|
907
|
+
// task 1004055: the same call also records the land proof, so a miss here is not
|
|
908
|
+
// cosmetic — check it rather than firing and forgetting. Not fatal on this path:
|
|
909
|
+
// the branch is pushed and the PR lands regardless, so say what to do IF the ship
|
|
910
|
+
// is later refused, and carry on.
|
|
911
|
+
const gateProof = await attestGateTrust(taskId, headSha);
|
|
912
|
+
if (!gateProof.recorded) {
|
|
913
|
+
for (const line of landProofWarningLines(taskId, headSha, gateProof.reason, { merged: false })) console.log(line);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// Ensure exactly one PR for this branch. gh pr create is idempotent-ish: it
|
|
917
|
+
// errors if a PR already exists, so check first and reuse it.
|
|
918
|
+
const existing = ghJson(['pr', 'view', branch, '--json', 'number,url,state']);
|
|
919
|
+
// Reusing an already-open PR means gate-review may have ALREADY run (red, before
|
|
920
|
+
// the attestation existed) on this same head SHA — nudge a re-run below.
|
|
921
|
+
const reusingOpenPr = !!(existing && existing.state === 'OPEN');
|
|
922
|
+
// PR titles + bodies are GitHub-rendered: a bare "#NNN" autolinks into
|
|
923
|
+
// GitHub's PR/issue number space (dead links for GDS task ids — task 916),
|
|
924
|
+
// so the task ref is written as "task NNN" and the summary is de-#-ed.
|
|
925
|
+
const title = `task ${taskId}: ${sanitizeGitHubRefs(valueSummary) || branch}`.slice(0, 240);
|
|
926
|
+
const deployTargetNote = resolveInstanceBase() || 'the configured instance';
|
|
927
|
+
const body =
|
|
928
|
+
`Auto-opened by ship.js (deploy mode: ci) for task ${taskId}.\n\n` +
|
|
929
|
+
`${sanitizeGitHubRefs(valueSummary) || '(no value summary)'}\n\n` +
|
|
930
|
+
`Merging this PR triggers .github/workflows/deploy-prod.yml to deploy to ` +
|
|
931
|
+
`${deployTargetNote}. ${prMergeSentence(hold)}`; // task 1004379: a held round's PR says it waits
|
|
932
|
+
if (!existing || existing.state === 'CLOSED' || existing.state === 'MERGED') {
|
|
933
|
+
console.log(' ci-land: opening PR -> main...');
|
|
934
|
+
if (!ghArgvOk(buildPrCreateArgv(branch, title, body))) {
|
|
935
|
+
console.log(' ci-land: `gh pr create` failed. Is the GitHub CLI installed + authenticated (`gh auth status`)? Open the PR manually; task stays at confirmed.');
|
|
936
|
+
return landBailed('`gh pr create` failed (is gh installed + authenticated?)', `node scripts/bongos/ship.js ${taskId}`);
|
|
937
|
+
}
|
|
938
|
+
} else {
|
|
939
|
+
console.log(` ci-land: reusing open PR ${existing.url}`);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// task 1004322: a held page tweak stops here — published, never armed.
|
|
943
|
+
if (hold) {
|
|
944
|
+
const pr = ghJson(['pr', 'view', branch, '--json', 'number,url,state']);
|
|
945
|
+
console.log(` ci-land: PR ${(pr && pr.url) || 'opened'} — auto-merge NOT armed: waiting for the artist.`);
|
|
946
|
+
return landHeld({ prUrl: (pr && pr.url) || null });
|
|
947
|
+
}
|
|
948
|
+
console.log(' ci-land: enabling auto-merge (lands when required checks pass)...');
|
|
949
|
+
// task 1718: an enable-failure is NOT a dead-end — the PR is open and the server
|
|
950
|
+
// still lands green PRs. Don't return false (which stranded the builder at
|
|
951
|
+
// 'confirmed' with no in-session SHIPPED banner); fall through to the server poll,
|
|
952
|
+
// which drives + observes the land. See landPollAfterAutoMerge.
|
|
953
|
+
const autoMergeArmed = ghArgvOk(buildPrMergeArgv(branch));
|
|
954
|
+
if (!autoMergeArmed) {
|
|
955
|
+
console.log(' ci-land: GitHub auto-merge could not be armed from here (normal when shipping from a worktree, or with branch protection off). The PR is open; the server lands it — waiting for the land instead of stranding at confirmed...');
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
// task 1169: if we REUSED an open PR, a stale red gate-review run may sit on this
|
|
959
|
+
// same head SHA from before the attestation existed; a new commit status does not
|
|
960
|
+
// re-trigger a pull_request check, so re-run it (best-effort). A freshly-opened PR
|
|
961
|
+
// is left alone — its single gate-review run reads the attestation and passes.
|
|
962
|
+
if (reusingOpenPr) rerunGateReviewIfStale(branch, headSha);
|
|
963
|
+
|
|
964
|
+
// enable-success watches GitHub directly; enable-failure drives + watches the
|
|
965
|
+
// server land (publish-status reconcile-on-read). Both flip to 'shipped' on a real
|
|
966
|
+
// land, so the banner renders in-session and no 'confirmed' breadcrumb is written.
|
|
967
|
+
return landPollAfterAutoMerge(autoMergeArmed) === 'ci'
|
|
968
|
+
? pollCiDeploy(taskId, branch, headSha)
|
|
969
|
+
: pollServerPublish(taskId, branch);
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
// Confirm the CI land actually reached production. Polls in stages:
|
|
973
|
+
// 1. PR state -> MERGED (checks passing + branch protection satisfied); grabs
|
|
974
|
+
// the merge commit oid.
|
|
975
|
+
// 2. the deploy-prod workflow run for that commit -> success.
|
|
976
|
+
// 3. public edge healthz -> 200 (belt-and-braces, a different vantage).
|
|
977
|
+
// Times out conservatively; on any timeout the task stays at confirmed with a
|
|
978
|
+
// precise next step rather than a false "shipped".
|
|
979
|
+
// `deps` exists for tests/ship_land_conflict.mjs; a real ship passes none.
|
|
980
|
+
function pollCiDeploy(taskId, branch, headSha, deps = {}) {
|
|
981
|
+
const MERGE_TRIES = 30; // ~5 min at 10s — checks + auto-merge
|
|
982
|
+
const DEPLOY_TRIES = 24; // ~4 min at 10s — Actions deploy
|
|
983
|
+
const readJson = deps.ghJson || ghJson;
|
|
984
|
+
const pause = deps.pause || (() => shellOk(POLL_SLEEP_CMD));
|
|
985
|
+
|
|
986
|
+
console.log(' ci-land: waiting for auto-merge (checks + branch protection)...');
|
|
987
|
+
let mergeSha = null;
|
|
988
|
+
let conflicting = false;
|
|
989
|
+
// task 1003764: say WHY it has not merged. This loop read only state + mergeCommit,
|
|
990
|
+
// so a red required check — the likeliest reason — went unnamed for the whole wait.
|
|
991
|
+
// The unit-report line (which failing tests) is fetched once per head sha.
|
|
992
|
+
let redLine = null;
|
|
993
|
+
let stuckRed = false;
|
|
994
|
+
let report = { sha: undefined, text: null };
|
|
995
|
+
const failingTestsFor = (sha) => {
|
|
996
|
+
if (sha !== report.sha) report = { sha, text: unitReportFor(sha, readJson) };
|
|
997
|
+
return report.text;
|
|
998
|
+
};
|
|
999
|
+
// task 1004289: a finished job's annotations never change, so each is read once.
|
|
1000
|
+
let notStarted = false;
|
|
1001
|
+
const startMemo = new Map();
|
|
1002
|
+
const neverStarted = (c) => {
|
|
1003
|
+
const key = String((c && c.detailsUrl) || '');
|
|
1004
|
+
if (!startMemo.has(key)) startMemo.set(key, jobNeverStarted(c, readJson));
|
|
1005
|
+
return startMemo.get(key);
|
|
1006
|
+
};
|
|
1007
|
+
for (let i = 0; i < MERGE_TRIES; i++) {
|
|
1008
|
+
// task 1003499: mergeable + mergeStateStatus ride the same read, so a conflict is
|
|
1009
|
+
// named on the poll it appears; the two-field read is the fallback for a gh that
|
|
1010
|
+
// predates those fields, which keeps this no worse than before on any machine.
|
|
1011
|
+
// task 1003764: so do headRefOid + statusCheckRollup, so a red check is named too.
|
|
1012
|
+
const pr = readJson(['pr', 'view', branch, '--json', 'state,mergeCommit,mergeable,mergeStateStatus,headRefOid,statusCheckRollup'])
|
|
1013
|
+
|| readJson(['pr', 'view', branch, '--json', 'state,mergeCommit']);
|
|
1014
|
+
if (pr && pr.state === 'MERGED') {
|
|
1015
|
+
mergeSha = pr.mergeCommit && pr.mergeCommit.oid;
|
|
1016
|
+
break;
|
|
1017
|
+
}
|
|
1018
|
+
if (pr && pr.state === 'CLOSED') {
|
|
1019
|
+
console.log(` ci-land: PR was CLOSED without merging (a required check failed, or it was closed manually). Fix it and re-run \`node scripts/bongos/ship.js ${taskId}\` to resume. Task stays at 'confirmed'.`);
|
|
1020
|
+
return landBailed('the PR was closed without merging (a check failed, or it was closed manually)', `node scripts/bongos/ship.js ${taskId}`);
|
|
1021
|
+
}
|
|
1022
|
+
if (pr) {
|
|
1023
|
+
const md = localMergeDriver(pr, failingTestsFor, neverStarted);
|
|
1024
|
+
const red = redPrLine(md);
|
|
1025
|
+
if (red && red !== redLine) {
|
|
1026
|
+
redLine = red;
|
|
1027
|
+
for (const line of redPrLines(md, { taskId, via: 'local' })) console.log(line);
|
|
1028
|
+
}
|
|
1029
|
+
stuckRed = !!red && redBlocksMerge(md);
|
|
1030
|
+
notStarted = !!(md && md.not_started);
|
|
1031
|
+
}
|
|
1032
|
+
conflicting = noteConflict(taskId, pr, conflicting);
|
|
1033
|
+
pause();
|
|
1034
|
+
}
|
|
1035
|
+
if (!mergeSha) {
|
|
1036
|
+
// task 1049: PR open + auto-merge armed but not merged in-window = the publish
|
|
1037
|
+
// SUCCEEDED and is still in CI — success-pending, not a failure. Unless it is
|
|
1038
|
+
// CONFLICTING (task 1003499): then nothing is still in CI, and it never merges.
|
|
1039
|
+
// Or RED (task 1003764): then the banner says the land is stuck on that check.
|
|
1040
|
+
if (conflicting) return landConflicted(taskId);
|
|
1041
|
+
printLandPending(taskId, { red: stuckRed, notStarted });
|
|
1042
|
+
return landPending();
|
|
1043
|
+
}
|
|
1044
|
+
console.log(` ci-land: merged to main (${mergeSha.slice(0, 8)}). Waiting for the prod deploy...`);
|
|
1045
|
+
|
|
1046
|
+
for (let i = 0; i < DEPLOY_TRIES; i++) {
|
|
1047
|
+
const runs = readJson([
|
|
1048
|
+
'run', 'list', '--workflow', 'deploy-prod.yml', '--branch', 'main',
|
|
1049
|
+
'--json', 'headSha,status,conclusion', '--limit', '15',
|
|
1050
|
+
]);
|
|
1051
|
+
if (deployRunSucceeded(runs, mergeSha)) {
|
|
1052
|
+
console.log(' ci-land: deploy-prod workflow succeeded for the merge commit.');
|
|
1053
|
+
// Commit-pin the confirmation against /version (#858) — stronger than a
|
|
1054
|
+
// liveness probe. The deploy run succeeding for OUR mergeSha is already
|
|
1055
|
+
// authoritative, so /version only refines the message (and never turns a
|
|
1056
|
+
// real deploy into a false negative on a transient miss or a concurrent
|
|
1057
|
+
// later deploy).
|
|
1058
|
+
const status = deployedCommitStatus(fetchDeployedVersion(), mergeSha);
|
|
1059
|
+
const instanceBase = resolveInstanceBase();
|
|
1060
|
+
const healthzUrl = instanceBase ? `${instanceBase}/healthz` : null;
|
|
1061
|
+
if (status === 'match') {
|
|
1062
|
+
console.log(' ci-land: /version confirms prod is live on the merge commit (commit-pinned).');
|
|
1063
|
+
} else if (status === 'mismatch') {
|
|
1064
|
+
console.log(' ci-land: deploy run succeeded; /version shows a different commit (a later deploy has since superseded it — fine, our change is in main).');
|
|
1065
|
+
} else if (healthzUrl && shellOk(`curl -fsS --max-time 10 ${healthzUrl} -o /dev/null`)) {
|
|
1066
|
+
console.log(` ci-land: /version unavailable; ${healthzUrl} 200 — treating the successful deploy run as authoritative.`);
|
|
1067
|
+
} else {
|
|
1068
|
+
console.log(' ci-land: deploy run succeeded but /version + healthz probes both missed (likely transient). Treating the successful deploy run as authoritative.');
|
|
1069
|
+
}
|
|
1070
|
+
return landed();
|
|
1071
|
+
}
|
|
1072
|
+
pause();
|
|
1073
|
+
}
|
|
1074
|
+
// task 1049: merged but the deploy run hasn't confirmed in-window — still
|
|
1075
|
+
// success-pending (it deploys on its own), not a failure.
|
|
1076
|
+
printLandPending(taskId, { merged: true });
|
|
1077
|
+
return landPending();
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
module.exports = {
|
|
1081
|
+
localHistoryRewritten, // task 1003221 — the append-only discriminator
|
|
1082
|
+
pushDiagnosis, // task 1003293 — a terminal push failure must not advise a retry
|
|
1083
|
+
PUSH_DIAGNOSES,
|
|
1084
|
+
ciLand,
|
|
1085
|
+
classifyLandOutcome,
|
|
1086
|
+
formatPublishFailure,
|
|
1087
|
+
// task 1004055: the land-proof half of attest-gate. attestGateTrust is exported
|
|
1088
|
+
// so the LOCAL-merge path can record a proof it previously never recorded at all;
|
|
1089
|
+
// the two pure halves so the truth table + the wording are pinned without a server.
|
|
1090
|
+
attestGateTrust,
|
|
1091
|
+
landProofRecorded,
|
|
1092
|
+
landProofWarningLines,
|
|
1093
|
+
// task 1002572 (PART 2): the bail ids + the pure "can a PR still land this?"
|
|
1094
|
+
// decision, so the single-checkout fallback is opt-in per bail and unit-tested.
|
|
1095
|
+
LAND_BAIL_MAIN_CHECKOUT_ON_BRANCH,
|
|
1096
|
+
LAND_BAIL_NO_TASK_BRANCH,
|
|
1097
|
+
landBailRecoverableByPr,
|
|
1098
|
+
landBailed,
|
|
1099
|
+
landHeld,
|
|
1100
|
+
landPending,
|
|
1101
|
+
landPendingLines,
|
|
1102
|
+
landPollAfterAutoMerge,
|
|
1103
|
+
landed,
|
|
1104
|
+
pickStaleGateReviewRun,
|
|
1105
|
+
reconcileBlockedLines,
|
|
1106
|
+
prAssigneeLine,
|
|
1107
|
+
redPrLine,
|
|
1108
|
+
redPrLines,
|
|
1109
|
+
// task 1003499: a CONFLICTING PR is named while the land waits, and a wait that
|
|
1110
|
+
// ends conflicting is a bail, not "landing automatically". The polls are exported
|
|
1111
|
+
// with their optional `deps` so the test drives the real loops.
|
|
1112
|
+
prConflicting,
|
|
1113
|
+
conflictPrLines,
|
|
1114
|
+
landConflicted,
|
|
1115
|
+
pollCiDeploy,
|
|
1116
|
+
pollServerPublish,
|
|
1117
|
+
// task 1003764: name WHY a published PR has not merged when a check is red.
|
|
1118
|
+
FRESHNESS_TESTS,
|
|
1119
|
+
failingTestNames,
|
|
1120
|
+
mergeTrapLines,
|
|
1121
|
+
redBlocksMerge,
|
|
1122
|
+
localMergeDriver,
|
|
1123
|
+
unitReportFor,
|
|
1124
|
+
// task 1004289: CI that never ran is said as such, not as a failure to fix.
|
|
1125
|
+
jobNeverStarted,
|
|
1126
|
+
notStartedLines,
|
|
1127
|
+
reconciledCardStatus,
|
|
1128
|
+
strandCommand,
|
|
1129
|
+
strandNextStep,
|
|
1130
|
+
};
|