@1aboveio/skills 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +3 -0
- package/README.md +90 -0
- package/bin/1aboveio-skills.mjs +18 -0
- package/package.json +28 -0
- package/runtime/skills/distribution/generated/recipes.json +1189 -0
- package/runtime/skills/distribution/scripts/bundles.mjs +280 -0
- package/runtime/skills/engineering/engineering-runtime/scripts/main-module.mjs +80 -0
- package/skills/backend/airflow-dag-develop/LICENSE +3 -0
- package/skills/backend/airflow-dag-develop/SKILL.md +111 -0
- package/skills/backend/app-debug/LICENSE +3 -0
- package/skills/backend/app-debug/SKILL.md +109 -0
- package/skills/backend/app-debug/references/common-errors.md +128 -0
- package/skills/backend/python-backend/LICENSE +3 -0
- package/skills/backend/python-backend/SKILL.md +326 -0
- package/skills/cicd-pipeline/cloud-build/LICENSE +3 -0
- package/skills/cicd-pipeline/cloud-build/SKILL.md +707 -0
- package/skills/cicd-pipeline/cloud-debug/LICENSE +3 -0
- package/skills/cicd-pipeline/cloud-debug/SKILL.md +316 -0
- package/skills/cicd-pipeline/cloud-debug/references/build-failures.md +238 -0
- package/skills/cicd-pipeline/cloud-debug/references/deploy-failures.md +376 -0
- package/skills/cicd-pipeline/cloud-debug/references/pipeline-failures.md +378 -0
- package/skills/cicd-pipeline/cloud-deploy/LICENSE +3 -0
- package/skills/cicd-pipeline/cloud-deploy/SKILL.md +229 -0
- package/skills/cicd-pipeline/cloud-deploy/references/config-templates.md +257 -0
- package/skills/cicd-pipeline/docker/LICENSE +3 -0
- package/skills/cicd-pipeline/docker/SKILL.md +126 -0
- package/skills/cicd-pipeline/google-cloud/LICENSE +3 -0
- package/skills/cicd-pipeline/google-cloud/SKILL.md +118 -0
- package/skills/cicd-pipeline/google-cloud/references/gcs.md +469 -0
- package/skills/cicd-pipeline/google-cloud/references/iam.md +451 -0
- package/skills/cicd-pipeline/google-cloud/references/project.md +349 -0
- package/skills/cicd-pipeline/google-cloud/references/secrets.md +336 -0
- package/skills/cicd-pipeline/google-cloud/references/vpc.md +312 -0
- package/skills/cicd-pipeline/google-cloud/scripts/create-sa.sh +36 -0
- package/skills/cicd-pipeline/google-cloud/scripts/gcp-config.sh +31 -0
- package/skills/cicd-pipeline/google-cloud/scripts/grant-iap.sh +41 -0
- package/skills/cicd-pipeline/google-cloud/scripts/setup-secrets.sh +48 -0
- package/skills/cicd-pipeline/mergify/LICENSE +3 -0
- package/skills/cicd-pipeline/mergify/SKILL.md +138 -0
- package/skills/cicd-pipeline/mergify/assets/templates/mergify.yml +237 -0
- package/skills/cicd-pipeline/mergify/assets/templates/ruleset.json +46 -0
- package/skills/cicd-pipeline/mergify/references/branch-protection.md +277 -0
- package/skills/cicd-pipeline/mergify/references/configuration.md +183 -0
- package/skills/cicd-pipeline/mergify/references/diagnosis.md +73 -0
- package/skills/cicd-pipeline/mergify/references/traps.md +78 -0
- package/skills/cicd-pipeline/mergify/references/watch-contract.md +218 -0
- package/skills/cicd-pipeline/mergify/scripts/audit-core.mjs +131 -0
- package/skills/cicd-pipeline/mergify/scripts/audit.mjs +4 -0
- package/skills/cicd-pipeline/mergify/scripts/watch-pr-delivery-core.mjs +663 -0
- package/skills/cicd-pipeline/mergify/scripts/watch-pr-delivery.mjs +4 -0
- package/skills/cicd-pipeline/podman/LICENSE +3 -0
- package/skills/cicd-pipeline/podman/SKILL.md +70 -0
- package/skills/cicd-pipeline/podman/agents/openai.yaml +4 -0
- package/skills/cicd-pipeline/podman/assets/templates/podman-compose-socket-directory.yml +6 -0
- package/skills/cicd-pipeline/podman/assets/templates/podman-service-override.conf +3 -0
- package/skills/cicd-pipeline/podman/references/compose-compatibility.md +70 -0
- package/skills/cicd-pipeline/podman/references/networking-and-ports.md +74 -0
- package/skills/cicd-pipeline/podman/references/rootless-services-and-sockets.md +156 -0
- package/skills/cicd-pipeline/podman/references/troubleshooting.md +98 -0
- package/skills/engineering/e2e-test/LICENSE +3 -0
- package/skills/engineering/e2e-test/SKILL.md +156 -0
- package/skills/engineering/e2e-test/assets/ci-gates.cloudbuild.yaml +272 -0
- package/skills/engineering/e2e-test/assets/ci-gates.github.yml +451 -0
- package/skills/engineering/e2e-test/assets/e2e-workflow.yml +282 -0
- package/skills/engineering/e2e-test/references/authoring/auth-flows.md +159 -0
- package/skills/engineering/e2e-test/references/authoring/playwright-config.md +71 -0
- package/skills/engineering/e2e-test/references/authoring/playwright-patterns.md +219 -0
- package/skills/engineering/e2e-test/references/authoring/test-skipping.md +44 -0
- package/skills/engineering/e2e-test/references/ci-integration.md +121 -0
- package/skills/engineering/e2e-test/references/ci-playwright-container.md +280 -0
- package/skills/engineering/e2e-test/references/debugging.md +36 -0
- package/skills/engineering/e2e-test/references/presentation-sweep.md +131 -0
- package/skills/engineering/e2e-test/references/reviewing.md +39 -0
- package/skills/engineering/e2e-test/references/route-discovery.md +50 -0
- package/skills/engineering/e2e-test/references/route-manifest.md +44 -0
- package/skills/engineering/e2e-test/scripts/detect-routes-fastapi.py +290 -0
- package/skills/engineering/e2e-test/scripts/detect-routes-nextjs.mjs +200 -0
- package/skills/engineering/e2e-test/scripts/post-visual-evidence.mjs +158 -0
- package/skills/engineering/e2e-test/scripts/presentation-checks.mjs +171 -0
- package/skills/engineering/e2e-test/scripts/presentation-perceivability.mjs +179 -0
- package/skills/engineering/e2e-test/scripts/presentation-reachability.mjs +154 -0
- package/skills/engineering/e2e-test/scripts/presentation-render-health.mjs +141 -0
- package/skills/engineering/e2e-test/scripts/presentation-sweep.mjs +148 -0
- package/skills/engineering/e2e-test/scripts/presentation-temporal.mjs +127 -0
- package/skills/engineering/e2e-test/scripts/presentation-visual.mjs +84 -0
- package/skills/engineering/e2e-test/scripts/project-route-manifest.mjs +75 -0
- package/skills/engineering/e2e-test/scripts/validate-manifest.mjs +106 -0
- package/skills/engineering/engineering-runtime/LICENSE +3 -0
- package/skills/engineering/engineering-runtime/SKILL.md +10 -0
- package/skills/engineering/engineering-runtime/agents/openai.yaml +6 -0
- package/skills/engineering/engineering-runtime/coherence/workflow.json +553 -0
- package/skills/engineering/engineering-runtime/scripts/exact-head-artifact.mjs +131 -0
- package/skills/engineering/engineering-runtime/scripts/head-check-set.mjs +398 -0
- package/skills/engineering/engineering-runtime/scripts/main-module.mjs +80 -0
- package/skills/engineering/engineering-runtime/scripts/mergify-yaml.mjs +11 -0
- package/skills/engineering/engineering-runtime/scripts/package-lock.json +43 -0
- package/skills/engineering/engineering-runtime/scripts/package.json +10 -0
- package/skills/engineering/engineering-runtime/scripts/required-check-plan.mjs +223 -0
- package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +576 -0
- package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +166 -0
- package/skills/engineering/ensure-coverage/LICENSE +3 -0
- package/skills/engineering/ensure-coverage/SKILL.md +136 -0
- package/skills/engineering/ensure-coverage/evals/evals.json +125 -0
- package/skills/engineering/ensure-coverage/references/breadth/coverage-ledger.md +91 -0
- package/skills/engineering/ensure-coverage/references/breadth/inventory-contract.md +83 -0
- package/skills/engineering/ensure-coverage/references/breadth/surface-baseline.md +44 -0
- package/skills/engineering/ensure-coverage/references/breadth/surface-discovery.md +16 -0
- package/skills/engineering/ensure-coverage/references/depth/characterization.md +68 -0
- package/skills/engineering/ensure-coverage/references/depth/coverage.config.example.json +25 -0
- package/skills/engineering/ensure-coverage/references/depth/grading.md +35 -0
- package/skills/engineering/ensure-coverage/references/depth/mock-policy.md +87 -0
- package/skills/engineering/ensure-coverage/references/depth/test-smells.md +23 -0
- package/skills/engineering/ensure-coverage/references/enforcement/ci-contract.md +164 -0
- package/skills/engineering/ensure-coverage/references/enforcement/hooks.md +85 -0
- package/skills/engineering/ensure-coverage/references/examples/coverage-ledger.md +109 -0
- package/skills/engineering/ensure-coverage/references/examples/refund-flow.md +33 -0
- package/skills/engineering/ensure-coverage/references/presentation/axis.md +78 -0
- package/skills/engineering/ensure-coverage/references/presentation/runner-contract.md +74 -0
- package/skills/engineering/ensure-coverage/references/process/audit-mode.md +33 -0
- package/skills/engineering/ensure-coverage/references/process/output-template.md +139 -0
- package/skills/engineering/ensure-coverage/references/process/review-contract-template.md +119 -0
- package/skills/engineering/ensure-coverage/references/process/scope-class.md +178 -0
- package/skills/engineering/ensure-coverage/references/process/test-strategy.md +55 -0
- package/skills/engineering/ensure-coverage/schemas/coverage-config.schema.json +45 -0
- package/skills/engineering/ensure-coverage/schemas/coverage-file.schema.json +93 -0
- package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.mjs +178 -0
- package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.mjs +101 -0
- package/skills/engineering/ensure-coverage/scripts/ci-audit.mjs +358 -0
- package/skills/engineering/ensure-coverage/scripts/coverage-checklist.mjs +494 -0
- package/skills/engineering/ensure-coverage/scripts/coverage-ledger.mjs +663 -0
- package/skills/engineering/ensure-coverage/scripts/design-parity.mjs +591 -0
- package/skills/engineering/ensure-coverage/scripts/evidence-block.mjs +367 -0
- package/skills/engineering/ensure-coverage/scripts/lint-tests.mjs +269 -0
- package/skills/engineering/ensure-coverage/scripts/mock-policy-config.mjs +176 -0
- package/skills/engineering/ensure-coverage/scripts/package-lock.json +76 -0
- package/skills/engineering/ensure-coverage/scripts/package.json +19 -0
- package/skills/engineering/ensure-coverage/scripts/scope-class.mjs +554 -0
- package/skills/engineering/harness-runtime/LICENSE +3 -0
- package/skills/engineering/harness-runtime/SKILL.md +18 -0
- package/skills/engineering/harness-runtime/agents/openai.yaml +6 -0
- package/skills/engineering/harness-runtime/bin/discover-models.mjs +4 -0
- package/skills/engineering/harness-runtime/bin/model-catalog.mjs +4 -0
- package/skills/engineering/harness-runtime/contracts.md +15 -0
- package/skills/engineering/harness-runtime/discover-models.mjs +392 -0
- package/skills/engineering/harness-runtime/fixtures/native-question-schemas.json +33 -0
- package/skills/engineering/harness-runtime/fixtures/question-responses.json +54 -0
- package/skills/engineering/harness-runtime/index.mjs +767 -0
- package/skills/engineering/harness-runtime/model-catalog.mjs +787 -0
- package/skills/engineering/harness-runtime/native-question-contracts.md +37 -0
- package/skills/engineering/harness-runtime/references/model-catalog-seed.json +159 -0
- package/skills/engineering/harness-runtime/references/model-catalog.md +57 -0
- package/skills/engineering/implement-and-pr/LICENSE +3 -0
- package/skills/engineering/implement-and-pr/SKILL.md +176 -0
- package/skills/engineering/implement-and-pr/references/ci-iteration.md +10 -0
- package/skills/engineering/implement-and-pr/references/closeout.md +27 -0
- package/skills/engineering/implement-and-pr/references/contract-complete-fix-rounds.md +34 -0
- package/skills/engineering/implement-and-pr/references/evidence-rules.md +39 -0
- package/skills/engineering/implement-and-pr/references/incremental-plan.md +16 -0
- package/skills/engineering/implement-and-pr/references/self-review.md +23 -0
- package/skills/engineering/implement-and-pr/references/tdd-mode.md +18 -0
- package/skills/engineering/resolve-issues/LICENSE +3 -0
- package/skills/engineering/resolve-issues/SKILL.md +167 -0
- package/skills/engineering/resolve-issues/generated/workflow-repair-policy.json +448 -0
- package/skills/engineering/resolve-issues/references/breaker.md +82 -0
- package/skills/engineering/resolve-issues/references/deliverables.md +27 -0
- package/skills/engineering/resolve-issues/references/delivery.md +108 -0
- package/skills/engineering/resolve-issues/references/evidence-lane.md +21 -0
- package/skills/engineering/resolve-issues/references/exact-head-ci.md +287 -0
- package/skills/engineering/resolve-issues/references/fan-out.md +33 -0
- package/skills/engineering/resolve-issues/references/finalization.md +68 -0
- package/skills/engineering/resolve-issues/references/guarantees.md +10 -0
- package/skills/engineering/resolve-issues/references/high-risk.md +29 -0
- package/skills/engineering/resolve-issues/references/incidents/848/README.md +156 -0
- package/skills/engineering/resolve-issues/references/intake.md +86 -0
- package/skills/engineering/resolve-issues/references/integration-gate.md +53 -0
- package/skills/engineering/resolve-issues/references/interference.md +87 -0
- package/skills/engineering/resolve-issues/references/loop.md +134 -0
- package/skills/engineering/resolve-issues/references/model-catalog.md +9 -0
- package/skills/engineering/resolve-issues/references/postmortem.md +27 -0
- package/skills/engineering/resolve-issues/references/pre-flight-model-slots.md +41 -0
- package/skills/engineering/resolve-issues/references/pre-flight-recording-and-checkout.md +48 -0
- package/skills/engineering/resolve-issues/references/pre-flight.md +41 -0
- package/skills/engineering/resolve-issues/references/regression-checklist.md +26 -0
- package/skills/engineering/resolve-issues/references/run-state.md +288 -0
- package/skills/engineering/resolve-issues/references/sandboxed-testing.md +48 -0
- package/skills/engineering/resolve-issues/references/spawn-contract.md +96 -0
- package/skills/engineering/resolve-issues/references/terminal-evidence-journal.md +40 -0
- package/skills/engineering/resolve-issues/references/why.md +653 -0
- package/skills/engineering/resolve-issues/schemas/fix-round.schema.json +49 -0
- package/skills/engineering/resolve-issues/scripts/combine-and-verify.mjs +721 -0
- package/skills/engineering/resolve-issues/scripts/component-candidate.mjs +962 -0
- package/skills/engineering/resolve-issues/scripts/contract-revision.mjs +220 -0
- package/skills/engineering/resolve-issues/scripts/detect-delivery-mode.mjs +420 -0
- package/skills/engineering/resolve-issues/scripts/detect-target-branch.mjs +256 -0
- package/skills/engineering/resolve-issues/scripts/detect-workspace-mode.mjs +168 -0
- package/skills/engineering/resolve-issues/scripts/discover-models.mjs +9 -0
- package/skills/engineering/resolve-issues/scripts/doctrine.mjs +62 -0
- package/skills/engineering/resolve-issues/scripts/evidence-lifecycle-contract.mjs +191 -0
- package/skills/engineering/resolve-issues/scripts/exact-head-ci.mjs +413 -0
- package/skills/engineering/resolve-issues/scripts/exact-head-github-provider.mjs +332 -0
- package/skills/engineering/resolve-issues/scripts/finalize.mjs +488 -0
- package/skills/engineering/resolve-issues/scripts/fix-rounds.mjs +3307 -0
- package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-circular-1001.json +16 -0
- package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-valid-sequencing.json +51 -0
- package/skills/engineering/resolve-issues/scripts/fixtures/fmm-express-830-component-candidate.json +17 -0
- package/skills/engineering/resolve-issues/scripts/fixtures/head-check-set-1081.json +166 -0
- package/skills/engineering/resolve-issues/scripts/gate-value-series.mjs +92 -0
- package/skills/engineering/resolve-issues/scripts/guide-index.mjs +73 -0
- package/skills/engineering/resolve-issues/scripts/head-check-set.mjs +159 -0
- package/skills/engineering/resolve-issues/scripts/interference.mjs +427 -0
- package/skills/engineering/resolve-issues/scripts/model-catalog.mjs +9 -0
- package/skills/engineering/resolve-issues/scripts/next-operations.mjs +419 -0
- package/skills/engineering/resolve-issues/scripts/postmortem.mjs +909 -0
- package/skills/engineering/resolve-issues/scripts/preflight-questions.mjs +322 -0
- package/skills/engineering/resolve-issues/scripts/reconcile-contained-unit-prs.mjs +415 -0
- package/skills/engineering/resolve-issues/scripts/release-state-contract.mjs +697 -0
- package/skills/engineering/resolve-issues/scripts/report.mjs +494 -0
- package/skills/engineering/resolve-issues/scripts/required-check-plan.mjs +172 -0
- package/skills/engineering/resolve-issues/scripts/round-metadata.mjs +79 -0
- package/skills/engineering/resolve-issues/scripts/run-state-review6-cases.mjs +334 -0
- package/skills/engineering/resolve-issues/scripts/run-state.mjs +4784 -0
- package/skills/engineering/resolve-issues/scripts/sandbox-selftest.mjs +395 -0
- package/skills/engineering/resolve-issues/scripts/spawn-contract.mjs +290 -0
- package/skills/engineering/resolve-issues/scripts/terminal-dispositions.mjs +170 -0
- package/skills/engineering/resolve-issues/scripts/terminal-evidence-journal.mjs +293 -0
- package/skills/engineering/resolve-issues/scripts/unit-kind.mjs +197 -0
- package/skills/engineering/resolve-issues/scripts/unit-lifecycle.mjs +127 -0
- package/skills/engineering/resolve-issues/scripts/watch-delivery.mjs +893 -0
- package/skills/engineering/resolve-issues/scripts/workspaces.mjs +829 -0
- package/skills/engineering/resolve-issues/workflows/independent-review.workflow.js +290 -0
- package/skills/engineering/resolve-issues/workflows/prior-art-scan.workflow.js +80 -0
- package/skills/engineering/resolve-issues/workflows/workflow-smoke.mjs +102 -0
- package/skills/engineering/resolve-release/LICENSE +3 -0
- package/skills/engineering/resolve-release/SKILL.md +112 -0
- package/skills/engineering/resolve-release/references/assembly.md +137 -0
- package/skills/engineering/resolve-release/references/auto-when-green.md +56 -0
- package/skills/engineering/resolve-release/references/candidate.md +167 -0
- package/skills/engineering/resolve-release/references/exposure.md +178 -0
- package/skills/engineering/resolve-release/references/handoff.md +24 -0
- package/skills/engineering/resolve-release/references/postmortem.md +230 -0
- package/skills/engineering/resolve-release/references/preflight.md +207 -0
- package/skills/engineering/resolve-release/references/principles.md +94 -0
- package/skills/engineering/resolve-release/references/regression-checklist.md +36 -0
- package/skills/engineering/resolve-release/references/related-skills.md +12 -0
- package/skills/engineering/resolve-release/references/routing.md +149 -0
- package/skills/engineering/resolve-release/references/verified-sha-github-flow.md +285 -0
- package/skills/engineering/resolve-release/references/versioning.md +202 -0
- package/skills/engineering/resolve-release/references/why.md +53 -0
- package/skills/engineering/resolve-release/scripts/adapter-completion-artifact.mjs +389 -0
- package/skills/engineering/resolve-release/scripts/build-changes.mjs +209 -0
- package/skills/engineering/resolve-release/scripts/candidate-hygiene.mjs +407 -0
- package/skills/engineering/resolve-release/scripts/candidate-identity.mjs +904 -0
- package/skills/engineering/resolve-release/scripts/candidate-traffic.mjs +81 -0
- package/skills/engineering/resolve-release/scripts/checked-adapter-loader.mjs +612 -0
- package/skills/engineering/resolve-release/scripts/close-attempt.mjs +135 -0
- package/skills/engineering/resolve-release/scripts/closeout-release.mjs +161 -0
- package/skills/engineering/resolve-release/scripts/doctrine.mjs +106 -0
- package/skills/engineering/resolve-release/scripts/durable-processing.mjs +522 -0
- package/skills/engineering/resolve-release/scripts/ensure-target-green.mjs +659 -0
- package/skills/engineering/resolve-release/scripts/evidence-bundle.mjs +1014 -0
- package/skills/engineering/resolve-release/scripts/finalize-release.mjs +526 -0
- package/skills/engineering/resolve-release/scripts/fixtures/durable-processing-adapter.mjs +169 -0
- package/skills/engineering/resolve-release/scripts/green-gate.mjs +599 -0
- package/skills/engineering/resolve-release/scripts/isolated-adapter-evaluator.mjs +752 -0
- package/skills/engineering/resolve-release/scripts/metadata-pr-status.mjs +56 -0
- package/skills/engineering/resolve-release/scripts/metadata-sync.mjs +1538 -0
- package/skills/engineering/resolve-release/scripts/postmortem.mjs +381 -0
- package/skills/engineering/resolve-release/scripts/preflight-probes.mjs +498 -0
- package/skills/engineering/resolve-release/scripts/production-endpoints.mjs +326 -0
- package/skills/engineering/resolve-release/scripts/rc-circuit-breaker.mjs +272 -0
- package/skills/engineering/resolve-release/scripts/report.mjs +417 -0
- package/skills/engineering/resolve-release/scripts/reprobe-credentials.mjs +114 -0
- package/skills/engineering/resolve-release/scripts/revalidate-candidate.mjs +238 -0
- package/skills/engineering/resolve-release/scripts/review-packet.mjs +503 -0
- package/skills/engineering/resolve-release/scripts/rollback-floor.mjs +263 -0
- package/skills/engineering/resolve-release/scripts/version-assert.mjs +339 -0
- package/skills/engineering/resolve-release/scripts/version-postmortem.mjs +485 -0
- package/skills/engineering/resolve-release/scripts/version.mjs +1199 -0
- package/skills/engineering/resolve-release/scripts/watch-candidate-delivery.mjs +449 -0
- package/skills/engineering/resolve-release/vendor/ACORN-LICENSE +21 -0
- package/skills/engineering/resolve-release/vendor/README.md +60 -0
- package/skills/engineering/resolve-release/vendor/acorn.mjs +6233 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/LICENSE +21 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/README.md +341 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/README.template.md +70 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs +7 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.mts +2033 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.ts +2033 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js +7 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/core/package.json +49 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/LICENSE +21 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/README.md +5 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.mts +549 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.ts +549 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/package.json +36 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/LICENSE +47 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/README.md +82 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.d.ts +11 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.mjs +22 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cjs +21 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.cjs +21 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.d.ts +11 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.d.ts +11 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.mjs +25 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.wasm +0 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.mts +85 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.ts +85 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.mts +20 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.ts +20 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs +2 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs.map +1 -0
- package/skills/engineering/resolve-release/vendor/quickjs/release-sync/package.json +61 -0
- package/skills/engineering/review-pr/LICENSE +3 -0
- package/skills/engineering/review-pr/SKILL.md +123 -0
- package/skills/engineering/review-pr/references/adversarial-reviewer-prompt.md +42 -0
- package/skills/engineering/review-pr/references/code-correctness.md +5 -0
- package/skills/engineering/review-pr/references/contract-freshness.md +9 -0
- package/skills/engineering/review-pr/references/coordination.md +18 -0
- package/skills/engineering/review-pr/references/domain-hazards.md +123 -0
- package/skills/engineering/review-pr/references/finding-themes.md +7 -0
- package/skills/engineering/review-pr/references/github-posting.md +98 -0
- package/skills/engineering/review-pr/references/golden-path-smoke.md +5 -0
- package/skills/engineering/review-pr/references/incremental-output.md +16 -0
- package/skills/engineering/review-pr/references/inputs-and-discovery.md +31 -0
- package/skills/engineering/review-pr/references/output-format.md +99 -0
- package/skills/engineering/review-pr/references/over-mock-screen.md +7 -0
- package/skills/engineering/review-pr/references/promotion-prs.md +16 -0
- package/skills/engineering/review-pr/references/re-review.md +18 -0
- package/skills/engineering/review-pr/references/review-method.md +199 -0
- package/skills/engineering/review-pr/references/review-mode.md +30 -0
- package/skills/engineering/review-pr/references/review-posture.md +53 -0
- package/skills/engineering/review-pr/references/round1-depth.md +62 -0
- package/skills/engineering/review-pr/references/scripts.md +17 -0
- package/skills/engineering/review-pr/references/workflow.md +16 -0
- package/skills/engineering/review-pr/schemas/findings.schema.json +282 -0
- package/skills/engineering/review-pr/scripts/finding-contract.mjs +285 -0
- package/skills/engineering/review-pr/scripts/post-review.mjs +405 -0
- package/skills/engineering/review-pr/scripts/pr-context.mjs +207 -0
- package/skills/engineering/review-pr/scripts/scan-diff.mjs +365 -0
- package/skills/engineering/review-pr/scripts/theme-contract.mjs +57 -0
- package/skills/engineering/smoke/LICENSE +3 -0
- package/skills/engineering/smoke/SKILL.md +131 -0
- package/skills/engineering/smoke/assets/smoke.manifest.example.json +53 -0
- package/skills/engineering/smoke/references/manifest.md +192 -0
- package/skills/engineering/smoke/scripts/smoke.mjs +713 -0
- package/skills/fullstack/better-auth/LICENSE +3 -0
- package/skills/fullstack/better-auth/SKILL.md +601 -0
- package/skills/fullstack/better-auth/references/feishu-api.md +270 -0
- package/skills/fullstack/monorepo/LICENSE +3 -0
- package/skills/fullstack/monorepo/SKILL.md +465 -0
- package/skills/fullstack/nextjs-fullstack/LICENSE +3 -0
- package/skills/fullstack/nextjs-fullstack/SKILL.md +210 -0
- package/skills/fullstack/nextjs-fullstack/conventions.md +318 -0
- package/skills/fullstack/nextjs-fullstack/frontend-conventions.md +61 -0
- package/skills/fullstack/nextjs-fullstack/nextjs16.md +287 -0
- package/skills/fullstack/nextjs-fullstack/server-actions.md +409 -0
- package/skills/fullstack/prisma-setup/LICENSE +3 -0
- package/skills/fullstack/prisma-setup/SKILL.md +180 -0
- package/skills/fullstack/prisma-setup/nextjs.md +258 -0
- package/skills/fullstack/prisma-setup/turborepo.md +301 -0
- package/skills/fullstack/shadcn/LICENSE +3 -0
- package/skills/fullstack/shadcn/SKILL.md +119 -0
- package/skills/fullstack/shadcn/assets/shadcn-small.png +0 -0
- package/skills/fullstack/shadcn/assets/shadcn.png +0 -0
- package/skills/fullstack/shadcn/cli.md +411 -0
- package/skills/fullstack/shadcn/customization.md +224 -0
- package/skills/fullstack/shadcn/evals/evals.json +90 -0
- package/skills/fullstack/shadcn/mcp.md +101 -0
- package/skills/fullstack/shadcn/rules/base-vs-radix.md +323 -0
- package/skills/fullstack/shadcn/rules/component-selection.md +67 -0
- package/skills/fullstack/shadcn/rules/composition.md +195 -0
- package/skills/fullstack/shadcn/rules/data-table.md +201 -0
- package/skills/fullstack/shadcn/rules/forms.md +255 -0
- package/skills/fullstack/shadcn/rules/icons.md +103 -0
- package/skills/fullstack/shadcn/rules/styling.md +167 -0
- package/skills/fullstack/zod-v4/LICENSE +3 -0
- package/skills/fullstack/zod-v4/SKILL.md +287 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Delivery — from `merge-ready` to a verified merge
|
|
2
|
+
|
|
3
|
+
This is the full procedure behind SKILL.md's [delivery rules](deliverables.md#deliverables-the-shippable-component-not-the-whole-epic). Read it when a component reaches `merge-ready`. The guarantee-4 statements it rests on stay in SKILL.md; this file is the mechanics, the probe rationale, the watch bound, and the dequeue routing.
|
|
4
|
+
|
|
5
|
+
**The one sentence everything here serves:** a merge tool's return code, a queue acknowledgement, and an auto-merge flag are all *requests*. Only ancestry is a result.
|
|
6
|
+
|
|
7
|
+
**And ancestry of *which* commit is the whole correctness of that check.** Pass the PR to `combine-and-verify.mjs delivered --sha <merge-sha> --target <branch> --pr <n>`: it takes the SHA from the PR's own merge record and refuses one that is merely the branch head. Under a merge-commit queue the head is an ancestor of the merge commit and passes by accident; under a **squash or rebase** queue the head lands nowhere, so the same honest caller gets "delivered" on one repo and "NOT delivered" for a genuinely merged PR on the next — and the loop hands back work that shipped. (PR #529 is the live case: merged as `bdbece5`, head `c770ae5`, both contained in `main`, which is exactly why this went unnoticed.)
|
|
8
|
+
|
|
9
|
+
**`merge-ready` is not an exit — it is a unit awaiting delivery, and delivery is gated like every other transition.** Every other move in this loop is refused in state when it is invalid; `merge-ready → merged` had no gate, no counter, and nothing refusable, so a unit could sit there forever and the manifest was never wrong. A component whose members reach `merge-ready` owes one **terminal delivery outcome**: `merged` — with a `mergedSha` **proved contained in the freshly-fetched `origin/<targetBranch>`** by [`combine-and-verify.mjs delivered`](../scripts/combine-and-verify.mjs) — or `handed-back`, with `blockedOn` quoting the unsatisfied condition **verbatim from the merge tool**. Anything else is in-flight, and the handoff reports every member **undelivered, not done**. A merge tool's return code, a queue acknowledgement, and an auto-merge flag are all *requests*; only ancestry is a result.
|
|
10
|
+
|
|
11
|
+
**Enqueue attempt stages (epic-867 / #946).** For canonical component delivery, the outward enqueue is one `attempt` (`outcome: "requested"` when the `@mergifyio queue` command is posted); acknowledgement, queue membership, unmet conditions, and subsequent queue states are component `observations`, not second attempts. A duplicate enqueue action in the same authorized generation is refused. The canonical record already owns the component PR, so a supplied attempt `pr` must match it. Historical unit delivery retains its original requested/waiting and one-pre-admission-requeue semantics for compatibility.
|
|
12
|
+
|
|
13
|
+
If those provider facts arrive while an actual resolver dependency is incoherent, append them to the [terminal provider evidence journal](terminal-evidence-journal.md). Appending changes no state. After coherence is restored, `run-state.mjs reconcile-terminal-evidence` reacquires provider/check/queue facts and fresh ancestry before the ordinary delivery transition can land. This is resolver delivery recovery only; #996 owns package/npm coherence and trusted repair.
|
|
14
|
+
|
|
15
|
+
**Enqueue attempt stages (epic-867 / #946).** For `queue:mergify`, do not invent an ack on the first post. Record `outcome: "requested"` when the `@mergifyio queue` comment is posted and there is not yet a 👍/status payload; promote to `outcome: "waiting"` with `ack: {kind, ref}` once the command is acknowledged **or** queue membership is observed. Optional field `pr` stores the PR number on multi-PR components. **One** re-queue at the same HEAD is allowed when every prior attempt at that HEAD is still pre-admission (`requested`, or `waiting` with `queueState: "not-enqueued"`); a second re-request or any prior `dequeued`/`rejected` at that HEAD still refuses (that is a failed-merge retry, not admission limbo). Example first post: `{"at":"…","action":"enqueue","headSha":"abc","outcome":"requested","pr":892}`.
|
|
16
|
+
|
|
17
|
+
(Named incident: epic-986 — manifest recorded `mergeShippable: true`, four units `merge-ready` with `lastVerdict: PASS` and their PR refs, and `mergedSha: null` on every one; the loop posted its queue request, got "waiting for queue conditions", and moved to the next unit. Twelve hours, one unsatisfied condition — `-draft`. epic-867 reconfirmed admission-limbo bookkeeping thrash under the old schema.)
|
|
18
|
+
|
|
19
|
+
**The merge path is a pre-flight decision (`deliveryMode`), and the wrong one fails silently in both directions.** `gh pr merge` on a merge-queue repo bypasses the queue or errors; an enqueue on a direct repo does nothing at all. Settle it with the mechanized probe — [`detect-delivery-mode.mjs`](../scripts/detect-delivery-mode.mjs) — never by reading repo files, and never by assuming. **A queue is a runtime fact, so ask it:** queue configuration commonly lives *outside* the repo (a Mergify `default` queue rule set dashboard-side), so a `.mergify.yml` check answers the wrong question. The probe fails closed — "no probe could run" and "probed and found no queue" are different states, and it returns `null` (exit 2) rather than a silent `direct` for the first. `record-component-delivery-attempt` refuses an action that does not belong to the run's mode (the legacy unit command enforces the same rule).
|
|
20
|
+
|
|
21
|
+
**`queue` is itself two flows, and the mode does not tell them apart.** `deliveryMode` picks the *state machine*; **`queueProvider` (`mergify` | `github`) picks the mechanics** — how you enqueue, where state is read, what the dequeue reasons are called, and whether a re-evaluation request or an acknowledgement exists at all. This file used to offer "`@mergifyio queue`, or `gh pr merge --auto`" as if those were two spellings of one action. They are not, and getting it wrong fails the same silent way the wrong *mode* does. Both come from the same probe, and **`run-state.mjs delivery-flow <slug>` answers which flow this run is in, with the exact commands** — ask it rather than reading the paragraphs below and choosing.
|
|
22
|
+
|
|
23
|
+
- **`direct`** — `gh pr merge`, one synchronous action, then the `delivered` post-condition. There is no queue to watch: a `delivery.watch` record in this mode is refused, because it means the run believes it is enqueueing.
|
|
24
|
+
- **`queue`** — **enqueue is three steps: make the PR eligible, request admission, and confirm the request was *processed*.**
|
|
25
|
+
- **Eligibility is a query, not a checklist.** Read the queue's own unmet-condition list for this PR and satisfy or hand back on each. Do not hardcode one: epic-986's twelve hours were spent on `-draft`, and the repo that taught us that has since *removed* `-draft` from its `queue_conditions` — while draft-ness still blocks the merge itself, because GitHub cannot merge a draft PR. The condition moved; it did not stop mattering. Hardcoding the last incident's condition is how the next one hides.
|
|
26
|
+
- **Open non-self `CHANGES_REQUESTED` is an eligibility failure, not a note** (epic-876 / #941). After independent PASS and before enqueue, list reviews whose `state` is `CHANGES_REQUESTED` and whose author is not the PR author (and not this run's own self-authored COMMENT). If any remain open, **do not enqueue**: reopen the unit with `reopenReason: external-review` and a new `authorizationBoundary: {kind: head, value: <fix-head>}`, fix the named class, and re-review. A bot that catches a dropped pre-move matrix row is a real AC gap; postmortem must not demote that round as a probable rebase.
|
|
27
|
+
- **Admission** is the provider's enqueue op (`ops.enqueue` from `delivery-flow`).
|
|
28
|
+
- **Acknowledgement**, where the provider has one. Mergify's enqueue is a PR comment, so it can simply go unread; the 👍 reaction (or its status-comment payload) is the evidence it did not. Recorded as `ack` on the attempt, and **required** — without it, "the queue is holding this PR" and "nobody read the comment" are the same manifest record. GitHub's native enqueue is an API call that returns its own receipt, so it owes no ack.
|
|
29
|
+
|
|
30
|
+
Then **watch to a terminal queue outcome**. `waiting_for_batch`, `preparing`, `running`, `bisecting`, `waiting_for_previous_batches` and `waiting_for_merge` are all *keep watching* — and so is **`waiting-for-queue-conditions`**, the pre-admission state this model did not name until PR #529 spent minutes in it: command acknowledged, every condition green, and `mergify queue show` answering *"PR #529 is not in the merge queue"* while `queue status` answered *"Queue is empty"*. Both read exactly like "your enqueue never happened", which is the genuinely different state **`not-enqueued`**. Read pre-admission state from the provider's `ops.readPreAdmissionState` (for Mergify, its status comment carries a machine-readable payload plus the rendered condition tree), and record the unmet leaves verbatim in the observation — they are what a hand-back must quote, and an empty list is what makes a nudge legitimate.
|
|
31
|
+
|
|
32
|
+
**The nudge: one re-evaluation request, where the provider has one.** Pre-admission, unchanged past `DELIVERY_NUDGE_AFTER_MINUTES` (5), with nothing listed unmet, `record-component-delivery-observation` exits **5** and names the command — `@mergifyio refresh`. Spend it once (`record-component-delivery-nudge`), which restarts the stall clock once. This is **not** a retry of the merge path: it attempts nothing and touches no HEAD. It is capped at one because the evidence behind it is one observation — #529 was admitted within a poll of its refresh, which is correlation, not proof; if the refresh does nothing the stall bound still fires and the unit still hands back. What the cap buys is that being wrong costs one comment, while being right saves a healthy unit from handing back at the stall bound. The nudge is due at 5 minutes against that 10-minute bound, and spending it restarts the clock, so a nudged unit still gets a full bound afterwards. `github` has no such command, so no nudge is ever due there and recording one is refused.
|
|
33
|
+
|
|
34
|
+
**A queued PR's branch is frozen.** A push under an enqueued PR ejects it (`pull-request-updated`) — and this loop pushes for several ordinary reasons: an evidence-lane commit, a rebase, `mergify stack push`. Dequeue explicitly before writing to an enqueued branch. `validate` reports the drift (the head sitting in the queue vs the unit's latest round) rather than refusing the write, because the write is often already done by the time anyone looks.
|
|
35
|
+
|
|
36
|
+
**Do not empty-commit to re-trigger CI while a review or delivery is in flight** (epic-876 / #941). Prefer non-SHA-moving re-triggers (`gh run rerun`, workflow_dispatch, `@mergifyio refresh`). An empty commit under a live reviewer forces **head-drift** and buys a full re-review of an identical production tree. If the tip must move for CI, freeze the tip *before* spawning the reviewer — or, when `git diff OLD NEW` is empty of production paths, route as an **evidence re-attest** (`reviewSubject: evidence`, no adversarial re-read of unmoved code) rather than a full-scope review. Never use an empty commit as the default answer to "CI didn't fire after retarget/rebase."
|
|
37
|
+
|
|
38
|
+
**Hybrid/auto observation path (enqueueTrigger ∈ {hybrid, auto}) — #791 / issue-664 / identity#669.**
|
|
39
|
+
|
|
40
|
+
On a hybrid or pure-auto repo a PR can reach `targetBranch` **without** this loop posting `@mergifyio queue`. GitHub/Mergify merge on their auto conditions the moment the review is posted as an approval (or CI turns green). The skill used to optimise only for enqueue → watch queue → record outcome, so a unit could be **actually merged** while the run manifest still said `merge-ready` / **UNDELIVERED**, and the postmortem invented a multi-hour "delivery wait." Measured: PASS ~02:48, PR merged 03:01:28, `record-delivery-outcome` only at 10:23 after a human "check the progress."
|
|
41
|
+
|
|
42
|
+
After `lastVerdict: PASS` (any `enqueueTrigger`) with a known `pushedSha` / PR — **one background pipeline** (#792 / issue-664 / identity#669):
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
node watch-delivery.mjs --pr <n> --repo <owner/name> --head <pushedSha> …
|
|
46
|
+
poll CI on exact HEAD + PR lifecycle together
|
|
47
|
+
on MERGED (hybrid/auto may land without enqueue) → exit 0 + mergedSha + mergedAt
|
|
48
|
+
on CI red while OPEN → exit 5 + reason ci-failed (fold into fix round)
|
|
49
|
+
on head-drift (PR tip ≠ --head) → exit 4 + reason head-drift (re-review new head;
|
|
50
|
+
never merged/ci-failed for the old SHA)
|
|
51
|
+
on dequeued / closed / stalled → exit 4 + reason
|
|
52
|
+
on CI green + still OPEN → keep watching (enqueue/auto-merge may still fire;
|
|
53
|
+
pure-queue: enqueue first, then this same watch)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Exact-HEAD is fail-closed.** With `--head`, every terminal classification is for that SHA only. The watch compares `headRefOid` to the supplied tip before merge/CI outcomes: if the branch moved after PASS, exit 4 with `reason: head-drift` so the orchestrator re-reviews the rewritten head rather than recording delivery or CI failure against a stale SHA (guarantee 3).
|
|
57
|
+
|
|
58
|
+
The orchestrator only **records and routes** the terminal JSON — no foreground poll turns. Exit codes distinguish merged (0) / not-merged hand-back (4) / CI failed (5); never "still going" as success. Absolute ceiling is the existing stall + max minutes.
|
|
59
|
+
|
|
60
|
+
Rules that follow:
|
|
61
|
+
|
|
62
|
+
- **Do not require a prior `@mergifyio queue` before watching for terminal merge.** `watch-delivery.mjs` / `classifyPrState` already treat `state=MERGED` as terminal regardless of `everQueued`; the gap was the orchestrator only launching the watch after enqueue.
|
|
63
|
+
- **Launch the watch in the same turn as PASS+CI-pending**, not only after explicit enqueue. Pass `--head <pushedSha>` so CI red is a distinct exit 5. A hybrid unit that auto-merges mid-watch still ends the watch with exit 0 + `mergedSha` + `mergedAt` (merge wins over CI red while checks settle).
|
|
64
|
+
- **Record `mergedAt` on `record-component-delivery-outcome`** (from the watch terminal JSON / `gh pr view --json mergedAt`) so postmortem prefers the provider's merge clock over the separate canonical `outcomeAt` bookkeeping clock.
|
|
65
|
+
- **Do not leave the terminal outcome write until a human asks for progress.** `run-state.mjs progress` must not still report UNDELIVERED for a PR whose merge commit is already on `origin/<targetBranch>` once the watch has run.
|
|
66
|
+
|
|
67
|
+
For pure `manual` enqueueTrigger: make eligible → enqueue → same `--head` watch. Hybrid/auto adds the *observation without enqueue* branch; it does not replace the manual enqueue path.
|
|
68
|
+
|
|
69
|
+
**Run the watch as one launch, not as a foreground poll loop — [`watch-delivery.mjs`](../scripts/watch-delivery.mjs).** It observes only: it never enqueues, never merges, never records, and takes no merge authorization — the enqueue decision and the outcome write stay with the orchestrator, because those are guarantee 4's authorization and the audit trail. What moves off the main thread is the waiting.
|
|
70
|
+
|
|
71
|
+
The reason is context, not convenience. The orchestrator is a thin scheduler, and polling is the largest consumer of its turns: delivering one PR in this repo took **13 foreground `gh pr view` calls**, and a Pi session delivering an epic spent **71 polling calls** (36 `gh pr view`, 18 `gh pr checks`, 17 `mergify queue`) — none of which produced a decision. That run ended with the orchestrator hand-patching its own manifest JSON, which is what a full context window looks like from the outside. Launch it in the background (or as a spawn) and record the terminal answer when it lands; **exit 0 = merged with the merge commit, exit 4 = terminal but not merged** — it never exits 0 on a timeout, because "still going" and "finished" collapsing into one code is the epic-986 shape. Exit 0 is still not a proved merge: the ancestry check remains owed.
|
|
72
|
+
|
|
73
|
+
**Watching is bounded on stall, not on elapsed time** (`record-component-delivery-observation`, exit **4** = the component watch owes a hand-back). A unit can sit in `waiting_for_previous_batches` for a long time while genuinely progressing, so a flat timeout hands back healthy units; what separates wedged from slow-but-moving is whether the observed delivery surface ever changes. The stall key is **(PR state, queue state, position, labels, queue membership, CI fingerprint)** — not labels alone. Only a change to that key restarts the clock; a poll that observes the same picture is evidence of a stall, not of life. Past `deliveryWatchBoundMinutes` (default **10**) with no movement, the watch process exits 4 with the reason quoted. That default is deliberately the same number the watcher scripts use for their own stall bound (`--bound-minutes` / `--stall-minutes`): the script bounds the process doing the watching and this bounds what gets recorded about it, so a manifest bound larger than the script's would never be reached — the script hands back first and the orchestrator stops observing. Recording an observation is **refusable only on its own shape** — a missing `queueState`, or a delivery record already invalid for the run's mode — never on unrelated unit state, because a logging call that can hard-fail is one an orchestrator learns to stop making and a watch nobody writes is the failure this bound exists to end. For everything else the signal is the exit code and the `validate` warning, never a throw. **`frozen` and `waiting_schedule` hand back on first sight**, without waiting out the bound: the queue is already telling you what is wrong and no amount of waiting changes it (`waiting_schedule` can legitimately mean *Monday*, and holding a session open until then is never the answer). (epic-986 sat twelve hours on a queue state that never moved once.)
|
|
74
|
+
|
|
75
|
+
**A stalled watch is not always a stalled unit.** Exit 4 carries two different reasons that used to share one name:
|
|
76
|
+
|
|
77
|
+
| reason | What it means | Orchestrator route |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| `conditions-unmet` | Picture frozen **and** the queue is not holding the PR (or membership is unknown and labels do not say queued) | Unit-level hand-back; quote the condition; do not re-enqueue the same HEAD |
|
|
80
|
+
| `stall-while-queued` | Picture frozen **but** the queue still holds the PR (`queueActive` or `queued` label) — typically "Preparing checks" with no position movement while CI runs | **Not** a unit hand-back. In the same turn: `gh pr view --json state,mergedAt,mergeCommit` once; if MERGED, record `merged` + ancestry. If still OPEN, **relaunch** `watch-delivery.mjs` with the same `--head` (the absolute `--max-minutes` ceiling still bounds total wall time). Never record `outcome: handed-back` for the unit and never re-enqueue. |
|
|
81
|
+
| `unreadable` | Polls could not be read | Same as conditions-unmet for routing; fix the tool surface first |
|
|
82
|
+
|
|
83
|
+
Named incident: `issue-799-800-resolve-release` #807 / PR #810 — watch exited `conditions-unmet` after 10m of OPEN+`queued` with no key change while Mergify was preparing checks; the PR merged two minutes later; `record-delivery-outcome` landed only after a multi-hour session gap (`outcome-write-lag`). The root cause was the stall key ignoring queue membership and CI progress, plus treating every exit-4 stall as unit-terminal.
|
|
84
|
+
|
|
85
|
+
**And bounded absolutely at one hour, whatever the stall bound says.** The stall bound cannot catch a queue that keeps *moving* without ever finishing — movement is exactly what resets it — so `--max-minutes` is the backstop for that case, and it is capped at **60 minutes** in both watchers rather than left to the caller. A larger value is refused (exit 2), not clamped: a watch that outlives the session that launched it produces no verdict at all, while one that hands back at an hour produces a routable one. A batch takes minutes, so an hour of continuous movement without a merge is already a queue for a human to look at. Relaunch after a `stall-while-queued` or ceiling hand-back; do not raise the ceiling.
|
|
86
|
+
|
|
87
|
+
**Where the dequeue is *observed* is the queue skill's business, not this one's.** This file owns the routing — what a reason means for the loop's state machine — and it is deliberately provider-neutral, because `checks-failed` re-enters the loop whoever reported it. **How you notice a dequeue at all is Mergify-specific mechanics**, and the local `mergify` skill holds them in [`references/watch-contract.md`](../../../cicd-pipeline/mergify/references/watch-contract.md): the `queued`/`dequeued` label lifecycle, the fact that a still-open PR *losing* `queued` is a possible dequeue transition (GitHub can briefly expose neither label before adding `dequeued`), and the rule that a watcher which has already observed queue entry must **never** keep reporting `{"queued": false}` as a routine healthy snapshot — that reading is a queue exit unless the PR merged. Read it there rather than re-deriving it here; two watch disciplines that each know half of this is how a wedged unit reads as a healthy one. For Mergify-backed simple deliveries, prefer `../../../cicd-pipeline/mergify/scripts/watch-pr-delivery.mjs`; `watch-delivery.mjs` remains the resolve-issues wrapper that records and routes the terminal answer.
|
|
88
|
+
|
|
89
|
+
The one premise worth carrying across the seam, because a reader who skips the pointer will otherwise build the wrong shape: **a watch observes a progression, not a state.** No single reading distinguishes "not admitted yet" from "dequeued" — that verdict is a *transition*, and it depends on what the watcher already saw. So a watch is one long-lived process carrying its own history (`everQueued`, the absent-read streak, readable-vs-absent, the change clock), never a stateless predicate a background runner re-evaluates each tick. Both watchers here are that process; do not wrap either in an outer poller, and do not hand-roll a `gh pr view` snippet in its place. Pi session `019fae8f` is what that costs: four hand-rolled watchers for one PR, none able to see a dequeue, one reporting a false `DEQUEUED` on a healthy PR.
|
|
90
|
+
|
|
91
|
+
**The skill never retries the merge path — the queue already retries exactly what should be retried.** A red batch is resolved by the queue's own `bisecting` state and the innocent PRs carry on; what a queue pointedly does *not* auto-retry is a PR whose own checks failed, because that loops forever on broken code. So a second attempt at an unchanged HEAD is refused. Re-entry to the merge path is earned by a fix and a fresh verdict, never repeated by the orchestrator. A dequeue is classified by a reason **read from the queue tool, never inferred** (the same rule as the reviewer's `subject: code|evidence` — the tool observed it and you did not):
|
|
92
|
+
|
|
93
|
+
**Record the queue's own string in `rawReason`; the routing class in `reason`.** The canonical classes below are *routes*, and the queue's vocabulary is wider than they are — Mergify's `queue-dequeue-reason` type alone carries ~40 values. Demanding one of five "read from the tool, never inferred" was self-contradictory: the tool says `pull-request-updated` and the taxonomy accepted neither that string nor any honest translation. `dequeueRouting()` owns the mapping, a `reason` that contradicts its `rawReason` is refused, and **anything unmapped routes to a hand-back** — a reason the table has never seen is not evidence about the code.
|
|
94
|
+
|
|
95
|
+
| reason (raw → class) | routing |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `checks-failed` | back to `in-progress` → fix round → **fresh independent verdict** (guarantee 3) → a new enqueue. The queue tests *PR merged with base* — a tree that never existed at review time and that per-PR CI structurally cannot have covered, so an ejection there is new information about code about to land, and it is a round of this loop rather than a delivery retry. |
|
|
98
|
+
| `pull-request-updated`, `draft-pull-request-changed` | same route, different cause: **HEAD moved under the queue**, so the verdict that authorized this delivery is stale. Usually the loop's own push — see the branch freeze above. |
|
|
99
|
+
| `conflict`, `conflict-with-base-branch` | **Provider-observed conflict only:** enter the [evidence lane](loop.md#3--fix-then-loop), reconcile according to the repository's queue policy, re-verify, then enqueue the new HEAD. Mere target advancement or GitHub `DIRTY` before enqueue is not this route in a batched Mergify queue: Mergify owns synthetic current-base integration. |
|
|
100
|
+
| `conditions-unmet` / `frozen` / `manual` / `pr-manually-dequeued` / `checks-timeout` | **hand back**, naming the condition and, for a pause, its reason — never queue over a human. A timeout is not evidence the code is broken, and re-enqueueing the same HEAD is refused anyway. |
|
|
101
|
+
| `stall-while-queued` | **not a unit hand-back** — the *watch process* ended on a frozen picture while the queue still holds the PR. Re-observe once (`gh pr view`); if MERGED, record delivery; if still OPEN, relaunch the same `--head` watch. Do not re-enqueue. (Watch-local reason from `watch-delivery.mjs`; not a Mergify dequeue class.) |
|
|
102
|
+
| anything else | **hand back** — the fail-closed default, with the raw string quoted |
|
|
103
|
+
|
|
104
|
+
**Deliver a shippable component into `targetBranch` only when pre-flight recorded `mergeShippable` and the mode-specific live gate passes.** The decision is read from the manifest, never supplied as a flag. For direct delivery, `combine-and-verify.mjs mergeable` requires exact target-tip integration before `gh pr merge`. For queue delivery, `combine-and-verify.mjs enqueue-eligible` requires the immutable frozen PR head, PR-head CI, dependencies, required-check evidence mapping, and live proof that `baseShaAtAssemble` remains an ancestor of the target. Forward target movement is allowed because a batched Mergify queue tests a synthetic current-base plus candidate tree; rewritten or divergent target history is blocked. Post one provider enqueue only after exit 0, then use the canonical watcher. **Do not rebase merely because the target advanced, and never run `gh pr merge` in a Mergify queue flow.** Absent authorization, hand the component back merge-ready and merge nothing.
|
|
105
|
+
|
|
106
|
+
**Queue execution proof is post-delivery evidence, not enqueue evidence.** The canonical watcher receives `--required-check-plan` and `--queue-execution-provider <resolve-issues>/scripts/exact-head-github-provider.mjs`, and sends the same exact `read-queue-execution` JSON request to that provider on every poll. While Mergify is active, the provider reads the status payload's `speculative_check_pr`, resolves that draft's distinct head, and returns a non-authorizing `queue-execution-observation` with the synthetic PR/SHA and available required queue-head check names/states. Synthetic checks changing queued → running → success restart the no-change clock even when the source PR's queue-only check is expectedly skipped; repeated observations still stall, and all progress remains subject to the absolute ceiling.
|
|
107
|
+
|
|
108
|
+
On `MERGED`, the provider read performs: (1) `gh pr view <pr> --json headRefOid,comments`, requiring the frozen PR SHA and exactly one Mergify merged-status `Checks passed on draft #<n>` identity; (2) `gh api repos/<owner>/<repo>/pulls/<n>` to resolve the distinct synthetic queue head; and (3) `gh api --paginate --slurp repos/<owner>/<repo>/commits/<queue-sha>/check-runs?per_page=100` to capture every required queue-head conclusion. The watcher independently validates the returned version-1 `queue-execution` artifact against repository, source PR/head, synthetic PR/head, planned provider, and every required successful check before exit 0. Empty output, malformed JSON, non-zero exit, timeout, any stderr, missing/duplicate/skipped/stale evidence, or an invalid artifact returns a distinct `evidenceBlocked` error and exit 4, never delivery success. On `MERGED`, prove both fresh `origin/<target>` ancestry and that artifact with `combine-and-verify.mjs queue-delivered`; if capture is blocked, record/hand back `evidence-blocked`. A red/dequeued batch follows ordinary routing; raw queue checks are diagnostic only and never forged into success.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# The evidence lane — a round that corrects a claim, not the code
|
|
2
|
+
|
|
3
|
+
This is the full procedure behind SKILL.md's [evidence lane](loop.md#3--fix-then-loop). Read it when a round looks like it is about the artifacts rather than the diff.
|
|
4
|
+
|
|
5
|
+
**Not every PASS is an evidence round (epic-867 / #948).** `evidenceClasses` and the evidence-audit warn apply when the round is correcting claims/evidence (typed `reviewSubject: "evidence"`, or a legacy `productionMoved: false` after the unit already saw a `NEEDS_CHANGES`). A clean first-pass PASS — single PASS, no prior fix loop — is ordinary produce+review success, not an evidence-lane spend. Do not invent `evidenceClasses` on those rounds; `evidence-audit` stays silent on a 4× first-pass epic.
|
|
6
|
+
|
|
7
|
+
**The routing rule stays in SKILL.md and is repeated here because getting it wrong skips the adversarial review:** both signals must hold — the production diff unmoved *and* every surviving finding classed `subject: evidence` by the reviewer. Either absent is an ordinary round.
|
|
8
|
+
|
|
9
|
+
Note the lane's own dependency: it reads production-diff emptiness from `evidence-block.mjs` as a **screen**, which still runs every round. That is unaffected by the attestation retiming — what moved to the terminal round is the stamped block, not the check.
|
|
10
|
+
|
|
11
|
+
- **This lane should now be rare.** Retiming the attestation to the terminal round (step 2) removes the *cause* of most evidence-only rounds rather than making them cheap: a stamp that is never regenerated mid-loop cannot go stale mid-loop. What remains is the residual — a rebase that moves the base, a checklist row citing a superseded locator. If this lane is still the common path after that change, the finding to chase is why the screens are not catching what the reviewer is catching, not how to make the lane faster.
|
|
12
|
+
- **Is this round even about the code? (check every round, healthy units included).** Two independent signals must both hold, and neither is your judgment about code you did not read. **(a) The production diff did not move** — read this from `evidence-block.mjs` (`--source`, comma-separated in one token), never a hand-rolled `git diff`: the tool already computes production-diff emptiness, stamps it to a HEAD, and surfaces it as a validate warning, and a second command in prose is how the two drift apart. Its hazard is documented in its own header and is worth knowing before you trust an `EMPTY`: git exits 0 on a pathspec matching nothing, so a mistyped or space-separated `--source` reads EMPTY on every run and would route every round into this lane. **`EMPTY` from a `--source` whose paths you have not seen resolve is not signal (a)** — that is the one failure this check cannot afford, since it fails *open*, straight past the adversarial review. **(b) The reviewer classed every surviving finding `subject: evidence`** (review-pr § Verdicts and the blocking bar) — the reviewer read the diff and you did not, so the classification is read, never inferred. Signal (a) alone is not enough: a forced full-scope round can surface a genuine code defect in code that has not moved since `lastReviewedSha`, and routing that into this lane skips exactly the adversarial re-review it needs. **Either signal absent → ordinary round.** With both, don't buy a producer spawn + adversarial re-review for a claim correction on unchanged code. Spend a narrow **evidence-fix spawn** instead — and note what it is *not*: it is not you editing the files. You coordinate, never implement, and that rule does not lapse because the diff is small; an orchestrator that hand-fixes a checklist is the same row-1 violation as one that hand-implements a unit.
|
|
13
|
+
|
|
14
|
+
> Read `<skillsRoot>/ensure-coverage/SKILL.md` (absolute) and follow its evidence/checklist doctrine; do not improvise. Subject: the findings classed `subject: evidence` on `<prRef>`, plus any validator left red by the step-2 pre-spawn check. **Touch no source file.** Your whole diff is confined to the evidence artifacts — the Review Contract block, the coverage checklist, the evidence block, and the docs the contract cites. **`@covers`/`@level` tags are not on that list**, because they live inside test files: editing one moves the production diff, and a lane that skips the adversarial review is the last place that should be able to touch a test — "fixing a tag" is exactly the cover an assertion-weakening edit would ride in under. If a finding cannot be fixed without a source change, **stop and report it unfixed** rather than making the change: that means the round was mis-routed and owes an ordinary fix round. Land one commit, then re-run `evidence-block.mjs validate` and `coverage-checklist.mjs validate <checklist> --diff <merge-base>` at the new HEAD and return both results stamped with that SHA. **The `--diff` is what makes the second one a re-check rather than a re-typing:** it resolves every locator you just wrote against the tree, so a correction that swaps one dead locator for another dead locator fails here instead of coming back as the same finding next round.
|
|
15
|
+
|
|
16
|
+
**Proof:** both validators green at the new HEAD **and** signal (a) still holding against it — the same `evidence-block.mjs` run that routed the round into this lane verifies the spawn honored its constraint, so the guard costs nothing extra. A source file in that diff means the lane was mis-routed: discard it and take an ordinary round, including the adversarial review. Then request the terminal review directly. The claims still have to be true — what changes is that a corrected claim over unmoved code is the validator's job, not an adversarial reviewer's.
|
|
17
|
+
- **A rebase or restack is this lane, not a new unit.** Moving the base changes which SHA the evidence cites while the production diff stays identical; that is an evidence refresh, and the correct response is to regenerate the block and revalidate — not to spend a fresh adversarial review re-reading code that did not move. (The contract-revision gate is the exception that overrides this: an *approved contract* landing on the target branch forces a full-scope review regardless.)
|
|
18
|
+
- **Batch them; one evidence round is the budget.** Fix every outstanding evidence finding in a single commit and revalidate once. A *second* consecutive evidence-only round means the validator is not catching what the reviewer is catching — fix that gap (or hand it to the human) rather than iterating claim corrections one at a time, and count the repeat toward the circuit-breaker like any other round.
|
|
19
|
+
- **A red external dependency is not a finding.** A flaky third-party gate or an unrelated CI timeout blocks *exit*, not the round: retry the gate, don't spend a review round rendering a verdict on it.
|
|
20
|
+
|
|
21
|
+
(Named incidents: three consecutive rounds of evidence-fidelity findings over an empty production diff; a unit whose reviewer wrote *"the implementation itself is correct at this head"* and blocked solely on a checklist citing a pre-restack base — then spent the next round rejecting the checklist fix; and two closing rounds on one PR where the second reviewed the identical SHA as the first, proving no code delta, because a flaky external gate had held the verdict.)
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Exact-head CI adapter
|
|
2
|
+
|
|
3
|
+
The adapter has two equally authoritative collection modes for one exact pull-request
|
|
4
|
+
head:
|
|
5
|
+
|
|
6
|
+
- `choreographed` temporarily mutates PR state, dispatches a workflow, restores the
|
|
7
|
+
original state, and proves restoration.
|
|
8
|
+
- `observed-existing-run` reads an already-running or completed provider workflow and
|
|
9
|
+
proves that the live PR head did not move while workflow and publish-only evidence
|
|
10
|
+
were acquired. It performs no PR mutation and makes no restoration claim.
|
|
11
|
+
|
|
12
|
+
Both modes use the same required-check plan, raw-job classification, publish-only
|
|
13
|
+
evidence validation, and downstream exact-head validator. Observation is not a
|
|
14
|
+
fallback or weaker evidence path; its provenance is different because no state was
|
|
15
|
+
mutated.
|
|
16
|
+
|
|
17
|
+
## The full check set at a head
|
|
18
|
+
|
|
19
|
+
The adapter above, and the required-check plan it consumes, answer **the name question**:
|
|
20
|
+
are the checks the plan names green? Neither asks **the set question**: what else is red at
|
|
21
|
+
this SHA? [`scripts/head-check-set.mjs`](../scripts/head-check-set.mjs) is that question. It
|
|
22
|
+
is a separate tool rather than a plan field because it has to be able to report a state the
|
|
23
|
+
plan has no vocabulary for.
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
node <resolve-issues>/scripts/head-check-set.mjs collect \
|
|
27
|
+
--repository owner/name --head <40-sha> \
|
|
28
|
+
[--plan required-check-plan.json] [--out head-check-set.json] [--markdown] [--strict]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Why three channels and not one.** #1081 shipped two workflows GitHub rejected at
|
|
32
|
+
validation time. At `ee5dd91a211d85f3158cbc4da8537b0cb1aee2d8` the observation was:
|
|
33
|
+
|
|
34
|
+
| channel | what it said |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `GET /commits/{sha}/check-runs` | 4 entries — every one `success`, `neutral` or `skipped` |
|
|
37
|
+
| `GET /commits/{sha}/status` | `pending`, zero statuses |
|
|
38
|
+
| `GET /actions/runs?head_sha=` | 3 runs — **two `failure`, zero jobs, `name` equal to `path`** |
|
|
39
|
+
|
|
40
|
+
Reading *all* check-runs rather than the named ones would still have reported that head
|
|
41
|
+
clean. A workflow GitHub cannot parse creates a run and produces no check-run to be red, so
|
|
42
|
+
the Actions channel is the only place it exists at all. The post-fix head `284d6ca6…`
|
|
43
|
+
reports `green` with those two runs **absent** — a workflow that merely stopped failing
|
|
44
|
+
would not have been proof.
|
|
45
|
+
|
|
46
|
+
**What it reports.** Three states that used to blur into one: a check that is required and
|
|
47
|
+
red; a check that is **not** required and red (informational); and a check that never ran at
|
|
48
|
+
all — the last carrying which absence it is: `no-run-anywhere` (the event was never
|
|
49
|
+
delivered; waiting is futile), `pending` (waiting is right), `dispatched-out-of-band`
|
|
50
|
+
(honest exact-head evidence that satisfies no queue condition), or
|
|
51
|
+
`absent-though-runs-completed` (#1058). Zero-job runs are named one by one in
|
|
52
|
+
`signatures.startupFailures`, never folded into a count.
|
|
53
|
+
|
|
54
|
+
**What it refuses to do.** `collect` exits **1 only on the required set** — a required check
|
|
55
|
+
red or absent, which the merge-admission contract already blocks on — and **0 on undeclared
|
|
56
|
+
red**, however loudly it reports it. Whether a non-required red check should stop a merge is
|
|
57
|
+
a policy decision belonging to the human and to `.mergify.yml`; a reporting script that
|
|
58
|
+
quietly changed what merges would be a worse defect than the one it fixes. `--strict` opts
|
|
59
|
+
in and nothing in the loop passes it. Omit `--plan` and nothing is classified required,
|
|
60
|
+
which degrades the tool to a pure observation of the SHA rather than a verdict.
|
|
61
|
+
|
|
62
|
+
## Choreographed Run
|
|
63
|
+
|
|
64
|
+
Before creating the request, discover and commit a versioned `required-check-plan.json` bound to the frozen component HEAD. The plan is the complete merge-admission contract, not a caller-selected job list. Use `required-check-plan.mjs` with live GitHub ruleset data, the live `.mergify.yml`, and explicit per-check mappings; it refuses an unmapped condition.
|
|
65
|
+
|
|
66
|
+
Create a request JSON that embeds that exact plan and run:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
node <resolve-issues>/scripts/exact-head-ci.mjs run \
|
|
70
|
+
--input exact-head-request.json \
|
|
71
|
+
--out exact-head-artifact.json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
For GitHub, point the provider at the bundled adapter:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"version": 1,
|
|
79
|
+
"collectionMode": "choreographed",
|
|
80
|
+
"repository": "owner/repository",
|
|
81
|
+
"pr": 123,
|
|
82
|
+
"expectedHeadSha": "0123456789abcdef0123456789abcdef01234567",
|
|
83
|
+
"provider": {
|
|
84
|
+
"command": "node",
|
|
85
|
+
"args": ["<resolve-issues>/scripts/exact-head-github-provider.mjs"],
|
|
86
|
+
"config": {
|
|
87
|
+
"ghCommand": "gh",
|
|
88
|
+
"queueProvider": "mergify",
|
|
89
|
+
"queueActiveLabels": ["queued"],
|
|
90
|
+
"queueDeactivateArgs": [
|
|
91
|
+
"pr",
|
|
92
|
+
"comment",
|
|
93
|
+
"{pr}",
|
|
94
|
+
"--repo",
|
|
95
|
+
"{repository}",
|
|
96
|
+
"--body",
|
|
97
|
+
"@mergifyio dequeue"
|
|
98
|
+
],
|
|
99
|
+
"creationTimeoutMs": 60000,
|
|
100
|
+
"creationPollIntervalMs": 1000
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"temporaryBase": "integration/epic-42",
|
|
104
|
+
"choreography": ["retarget", "close", "reopen", "dispatch"],
|
|
105
|
+
"workflow": {
|
|
106
|
+
"id": "CI Stages",
|
|
107
|
+
"ref": "feature-branch",
|
|
108
|
+
"inputs": {
|
|
109
|
+
"exact_head": "0123456789abcdef0123456789abcdef01234567"
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
"requiredCheckPlan": {
|
|
113
|
+
"version": 1,
|
|
114
|
+
"kind": "required-check-plan",
|
|
115
|
+
"repository": "owner/repository",
|
|
116
|
+
"targetBranch": "main",
|
|
117
|
+
"headSha": "0123456789abcdef0123456789abcdef01234567",
|
|
118
|
+
"discovery": {
|
|
119
|
+
"github": { "conditions": ["required_status_checks: Mergify Merge Protections"] },
|
|
120
|
+
"mergify": { "conditions": ["check-success = unit"] },
|
|
121
|
+
"requiredChecks": ["Mergify Merge Protections", "unit"]
|
|
122
|
+
},
|
|
123
|
+
"checks": [
|
|
124
|
+
{ "name": "Mergify Merge Protections", "admission": "required", "classification": "publish-only", "sources": ["github-ruleset"], "evidence": { "provider": "github", "reason": "published after PR creation" } },
|
|
125
|
+
{ "name": "unit", "admission": "required", "classification": "locally-reproduced", "sources": ["mergify"], "evidence": { "command": "node --test", "job": "unit", "result": "success" } }
|
|
126
|
+
],
|
|
127
|
+
"allowedSkippedJobs": ["merge-queue-only"]
|
|
128
|
+
},
|
|
129
|
+
"policy": {
|
|
130
|
+
"pollIntervalMs": 2000,
|
|
131
|
+
"timeoutMs": 1200000
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Observe An Existing Run
|
|
137
|
+
|
|
138
|
+
For a natural `pull_request` workflow already attached to the exact PR head, supply
|
|
139
|
+
its provider workflow and run identity. Do not include `temporaryBase`, `choreography`,
|
|
140
|
+
workflow dispatch `ref`, or workflow `inputs`:
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"version": 1,
|
|
145
|
+
"collectionMode": "observed-existing-run",
|
|
146
|
+
"repository": "owner/repository",
|
|
147
|
+
"pr": 123,
|
|
148
|
+
"expectedHeadSha": "0123456789abcdef0123456789abcdef01234567",
|
|
149
|
+
"provider": {
|
|
150
|
+
"command": "node",
|
|
151
|
+
"args": ["<resolve-issues>/scripts/exact-head-github-provider.mjs"],
|
|
152
|
+
"config": {
|
|
153
|
+
"ghCommand": "gh",
|
|
154
|
+
"queueProvider": "mergify",
|
|
155
|
+
"queueActiveLabels": ["queued"]
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"workflow": {
|
|
159
|
+
"id": "CI Stages",
|
|
160
|
+
"runId": 123456789
|
|
161
|
+
},
|
|
162
|
+
"requiredCheckPlan": "<the same complete plan shape shown above>",
|
|
163
|
+
"policy": {
|
|
164
|
+
"pollIntervalMs": 2000,
|
|
165
|
+
"timeoutMs": 1200000
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
The collector snapshots the live PR before reading the named run, polls that run to
|
|
171
|
+
completion, acquires provider-issued publish-only checks, then snapshots the live PR
|
|
172
|
+
again. Either snapshot, the workflow, or publish-only evidence naming another head
|
|
173
|
+
fails the artifact. The artifact contains `observation.before` and
|
|
174
|
+
`observation.after`; a `restoration`, `choreography`, or top-level choreography
|
|
175
|
+
`snapshot` field is invalid in this mode.
|
|
176
|
+
|
|
177
|
+
For `choreographed`, all repository-specific mutation and dispatch values are input:
|
|
178
|
+
repository, temporary base, choreography, workflow id/ref/inputs, a complete
|
|
179
|
+
`requiredCheckPlan`, provider executable, and queue detection/deactivation. For
|
|
180
|
+
`observed-existing-run`, the existing workflow/run identity replaces mutation and
|
|
181
|
+
dispatch values. `policy.requiredJobs` and `policy.allowedSkippedJobs` are legacy and rejected
|
|
182
|
+
with migration guidance; exact-head CI derives local required jobs and allowed skips from
|
|
183
|
+
the plan. `main` and `CI Stages` are examples, never defaults.
|
|
184
|
+
|
|
185
|
+
`queueActiveLabels` must describe the provider's live queue-membership signal. Use an
|
|
186
|
+
empty array only where no label represents membership. `queueDeactivateArgs` is a configured
|
|
187
|
+
`gh pr comment {pr} --repo {repository} --body <deactivation>` argument vector. The GitHub
|
|
188
|
+
provider accepts that exact shape only, requires the body to name `dequeue` or `unqueue`,
|
|
189
|
+
and rejects extra arguments or enqueue/approve/merge/review intent before invoking `gh`.
|
|
190
|
+
It may remove membership created during choreography but has no enqueue counterpart. The
|
|
191
|
+
adapter refuses an active queue snapshot before mutation: restoring it would require
|
|
192
|
+
enqueueing, which this adapter is structurally forbidden to do. Dequeue explicitly under
|
|
193
|
+
the delivery provider's own policy before collecting exact-head CI.
|
|
194
|
+
|
|
195
|
+
## Provider contract
|
|
196
|
+
|
|
197
|
+
The provider receives one JSON request on stdin and returns one JSON object. The only
|
|
198
|
+
operations are:
|
|
199
|
+
|
|
200
|
+
- `snapshot`
|
|
201
|
+
- `retarget`
|
|
202
|
+
- `set-open`
|
|
203
|
+
- `set-draft`
|
|
204
|
+
- `set-labels`
|
|
205
|
+
- `set-queue-inactive`
|
|
206
|
+
- `dispatch-workflow`
|
|
207
|
+
- `read-workflow`
|
|
208
|
+
- `read-publish-only-checks`
|
|
209
|
+
- `read-queue-execution`
|
|
210
|
+
|
|
211
|
+
There is no enqueue, approve, merge, review-write, or queue-write operation. A custom
|
|
212
|
+
provider may implement another host, but it must preserve the same operation vocabulary
|
|
213
|
+
and snapshot shape: base, full head SHA, open/draft booleans, exact label set, queue
|
|
214
|
+
object with boolean `active`, and relevant review state.
|
|
215
|
+
|
|
216
|
+
`read-workflow` receives the expected `runId`, `workflowId`, and full `headSha`. Its
|
|
217
|
+
response preserves the provider-issued workflow identity as
|
|
218
|
+
`workflow: { id, name, path? }` alongside the provider run id, head, status,
|
|
219
|
+
conclusion, and jobs. The adapter compares the configured selector with the provider
|
|
220
|
+
id, name, full path, or path basename before accepting jobs. The GitHub provider reads
|
|
221
|
+
`repos/<repository>/actions/runs/<runId>`, performs the same comparison against the
|
|
222
|
+
REST response's `workflow_id`, `name`, and `path`, and refuses a run-id, workflow, or
|
|
223
|
+
head mismatch before reading jobs.
|
|
224
|
+
|
|
225
|
+
## Artifact truth
|
|
226
|
+
|
|
227
|
+
Version 2 artifacts declare exactly one closed-vocabulary `collectionMode`. Every
|
|
228
|
+
artifact binds repository, PR, expected/workflow SHA, the requested workflow selector,
|
|
229
|
+
provider-issued workflow id/name/path, provider run identity, the versioned
|
|
230
|
+
required-check plan, derived provider-neutral policy, every raw job conclusion,
|
|
231
|
+
provider-issued publish-only evidence, and the derived outcome.
|
|
232
|
+
`choreographed` additionally records the original snapshot, mutation choreography,
|
|
233
|
+
all restoration attempts, final live snapshot, and whether restoration was proved.
|
|
234
|
+
`observed-existing-run` instead records live `before`/`after` observations and forbids
|
|
235
|
+
restoration or mutation claims. Every discovered check is classified
|
|
236
|
+
`locally-reproduced` or `publish-only`
|
|
237
|
+
with evidence. The plan preserves each Mergify lifecycle source as a `pr-head` or
|
|
238
|
+
`queue-head` phase: exact-head CI validates only PR-head evidence. Changed-path
|
|
239
|
+
exemptions remain structural and explicit in the phase tree; `skipped` remains
|
|
240
|
+
`skipped`, never satisfies a required job, and never becomes `success`.
|
|
241
|
+
|
|
242
|
+
A queue-head check is never bound to the frozen PR SHA. Its required-check-plan entry names a provider and acquisition path before enqueue, but no synthetic evidence is required for terminal PR-head authorization. During the queue watch, the canonical watcher sends one exact `read-queue-execution` request per poll to `exact-head-github-provider.mjs`. An active Mergify status payload's `speculative_check_pr` identifies the synthetic draft; the provider resolves its `head.sha` and required check runs, then returns a non-authorizing observation whose queued/running/success changes count as delivery progress.
|
|
243
|
+
|
|
244
|
+
After Mergify merges, the same request reads the merged status comment's unique synthetic draft PR, resolves that draft's `head.sha` through `gh api repos/<repo>/pulls/<draft>`, then reads `gh api --paginate --slurp repos/<repo>/commits/<queue-sha>/check-runs?per_page=100`. It emits a version-1 `queue-execution` artifact with the frozen `prHeadSha`, distinct synthetic `queuePr`/`queueHeadSha`, provider identity, and every required queue-head conclusion. The watcher validates the complete artifact before reporting success; provider IPC errors and absent, skipped, mismatched, ambiguous, or PR-SHA-bound queue evidence are `evidence-blocked`, never a completed delivery. `combine-and-verify.mjs queue-delivered` still requires both that valid artifact and fresh merge-commit ancestry.
|
|
245
|
+
|
|
246
|
+
A legacy artifact without `requiredCheckPlan` fails validation with actionable migration
|
|
247
|
+
guidance. This is deliberate: epic-892 passed a supplied resolver job set while omitting
|
|
248
|
+
deterministic `skill-size`, then moved the reviewed head after publication.
|
|
249
|
+
|
|
250
|
+
Both modes fail closed on malformed input/provider output, head drift, missing or
|
|
251
|
+
duplicate evidence, workflow identity mismatch, zero jobs, job failure/cancellation,
|
|
252
|
+
and disallowed skips. `choreographed` additionally fails on active queue membership,
|
|
253
|
+
workflow-creation failure, interruption, or restoration proof failure; `SIGINT` and
|
|
254
|
+
`SIGTERM` are recorded at the next operation boundary and still enter `finally`
|
|
255
|
+
restoration. `observed-existing-run` never enters a restoration path because it never
|
|
256
|
+
mutates PR state.
|
|
257
|
+
|
|
258
|
+
Validate independently at the SHA a consumer expects:
|
|
259
|
+
|
|
260
|
+
```sh
|
|
261
|
+
node <resolve-issues>/scripts/exact-head-ci.mjs validate exact-head-artifact.json --head <sha>
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Consumers recompute passability from raw jobs plus policy and enforce the selected
|
|
265
|
+
mode's provenance contract. A forged `status: pass`, green summary over failed jobs,
|
|
266
|
+
synthetic restoration on observation, or missing restoration after choreography is
|
|
267
|
+
rejected.
|
|
268
|
+
|
|
269
|
+
## Consumers
|
|
270
|
+
|
|
271
|
+
Review evidence:
|
|
272
|
+
|
|
273
|
+
```sh
|
|
274
|
+
node <ensure-coverage>/scripts/evidence-block.mjs collect \
|
|
275
|
+
--base <merge-base> --exact-head exact-head-artifact.json -o evidence.json
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Integration evidence:
|
|
279
|
+
|
|
280
|
+
```sh
|
|
281
|
+
node <resolve-issues>/scripts/combine-and-verify.mjs record-exact-head \
|
|
282
|
+
--in integration-verdict.json --artifact exact-head-artifact.json
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Newly assembled integration verdicts stamp `integrationHeadSha` and start
|
|
286
|
+
`gates.exactHead` at `pending`; they cannot reach `ALIVE` until this command accepts a
|
|
287
|
+
same-SHA artifact. The reduced integration evidence keeps every job conclusion.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Fan-out phases (Workflow harness)
|
|
2
|
+
|
|
3
|
+
Two **stages** — and only these two — are fanned out via the `Workflow` harness scripts shipped beside this skill (`workflows/`): the analysis stages in the table below. Everything else stays in the main loop, because the harness is headless (can't hit a human gate) and its agents must be *leaves* (it nests one level only):
|
|
4
|
+
|
|
5
|
+
- **Produce (step 1)** and **fix (step 3)** write code and can trip the "non-trivial unit lacks approved test criteria → stop and request them" gate — a human touchpoint. They stay in the main loop, spawned per-unit at depth 1 as the loop describes — **one at a time**, since every code-writing spawn works in the run's single checkout (see the scheduling rules); "main loop" means who launches them.
|
|
6
|
+
- **CI** pushes — outward-facing — and the review→fix→re-review loop is stateful against a moving HEAD. Main loop.
|
|
7
|
+
|
|
8
|
+
What's left for the harness is the no-code, non-interactive, fan-out analysis:
|
|
9
|
+
|
|
10
|
+
| Stage | Workflow script | Shape | Why it's safe to fan out |
|
|
11
|
+
|---|---|---|---|
|
|
12
|
+
| **Prior-art** (epics) | `workflows/prior-art-scan.workflow.js` | one read-only investigator per unit → routing verdict | Read-only `gh`/`git` queries. Writes no code, opens no PR, asks nothing. |
|
|
13
|
+
| **Independent review** | `workflows/independent-review.workflow.js` | one reviewer per unit's PR, **on the review model** | Read-only adversarial review. **Both independence guarantees hold:** fresh context (new subagent) + model diversity (`opts.model = reviewModel ≠ implementationModel`). |
|
|
14
|
+
|
|
15
|
+
**Why moving the review to a workflow does *not* break the depth-1 model-diversity rule:** the danger this skill guards against is nesting a *whole orchestrator* that then has to sub-spawn its reviewer (main → resolve-issues-subagent → review = depth 2, capped). A review *workflow* is different — **the main-loop orchestrator launches it directly**, and each review agent is a **leaf** that runs on the review model and never sub-spawns. So the reviewers sit at the single nesting level the harness allows, on a different model than the implementer — exactly the depth-1 sibling guarantee, just fanned out. The script hard-fails without a `reviewModel` and tags every result `independent: false` when `reviewModel === implementationModel`, so a same-model review can never be passed off as real (SKILL.md **guarantee 2** — independent review on a different model).
|
|
16
|
+
|
|
17
|
+
Both are **opt-in and optional** (running a workflow requires the user to opt into multi-agent orchestration). With one unit, or no opt-in, run prior-art and the review **inline** exactly as the step text describes — identical result, just sequential. The orchestrator scouts the work-list first (the unit roster; per-unit PR refs + prior findings for a re-review) and passes it via the host runner; the scripts don't discover their own inputs. To run one:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Workflow({ scriptPath: "<skillsRoot>/resolve-issues/workflows/<name>.workflow.js", args: {...} })
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
That generic form applies to both workflows, independent review included.
|
|
24
|
+
|
|
25
|
+
`<skillsRoot>` is the **absolute** skills directory resolved and recorded by [pre-flight](pre-flight.md) step 0 — a relative `skills/engineering/...` path only resolves inside the skills repo. The same rule applies to every skill path passed *into* a workflow: `independent-review.workflow.js` hard-fails unless `reviewSkillPath` is absolute, because a reviewer that can't read `review-pr/SKILL.md` silently improvises a lookalike review.
|
|
26
|
+
|
|
27
|
+
## Prior-art scan inputs/outputs
|
|
28
|
+
|
|
29
|
+
With more than a unit or two, run `prior-art-scan.workflow.js` (one read-only investigator per unit). It returns, per unit: the finding (`merged` / `open-pr` / `partial` / `nothing`), the evidence locators, a recommendation, and where the unit enters the loop (`skip` / `review` / `implement-remaining` / `implement`). Feed those into scheduling; with a single unit, just check inline.
|
|
30
|
+
|
|
31
|
+
## Review — independent-review inputs/outputs
|
|
32
|
+
|
|
33
|
+
To review (or re-review) several units' PRs at once, run `independent-review.workflow.js` (one reviewer per unit, each on `reviewModel` via `opts.model`, spawned at `reviewEffort` — the effort of the banked [operating point](model-catalog.md) confirmed for the review slot, defaulting to high). Pass `reviewModel`, `implementationModel`, `reviewSkillPath` (**absolute** — the script rejects a relative one), and per unit: `prRef`, `baseRef`, `contractPath`, its `highRisk` flag (routes the [high-risk reviewer additions](high-risk.md) — hazard hunt + round-1 depth), its own `implementationModel` when it differs from the run-level one (a substitute re-confirmed at spawn time — the diversity guard compares per unit), its `lastReviewedSha` on a re-review when delta scope applies (review-pr § Re-review; omit it to force full scope — high-risk, round 3+, delta outside the original files, or a rebase), and (on a re-review) its `priorFindings` so the reviewer emits the Previous Findings — Resolution Status table. The reviewer computes its own merge-base/range with review-pr's `pr-context.mjs` — no caller-supplied SHA plumbing. A state-machine/concurrency finding carries a durable theme `{ id, kind, contract, stateSpace }` (routine findings may omit `theme`); a recurring theme keeps the same id. The script enforces the diversity guard deterministically. Re-run against the new HEAD each round; the fix step stays in the main loop.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Correctness-only finalization
|
|
2
|
+
|
|
3
|
+
`run-state.mjs reconcile-contained-unit-prs <slug>` is the pre-finalization transition that can close a delivery-linked unit PR superseded by a merged combined component. It does so only after fresh target ancestry, exact reviewed-head identity, and live component merge-SHA verification. Terminal PRs are recorded no-ops; ambiguous facts leave the PR open.
|
|
4
|
+
|
|
5
|
+
`run-state.mjs finalize <slug>` remains the only transition that marks a `resolve-issues`
|
|
6
|
+
run complete. It does not trust reconciliation observations: it independently re-fetches and re-verifies the live facts below. A free-form completion object is never evidence: `completionAudit` is rejected by generic writes, validation, and finalization.
|
|
7
|
+
|
|
8
|
+
## What the transition proves
|
|
9
|
+
|
|
10
|
+
1. Every implementation unit has one honest typed disposition: `delivered`,
|
|
11
|
+
`handed-back`, `already-done`, or human `descoped`. Blocked, merge-ready without an
|
|
12
|
+
outcome, and missing/contradictory evidence fail closed.
|
|
13
|
+
2. Every external-verification, human-decision, and prerequisite unit is **settled**: complete
|
|
14
|
+
under its #884 protocol, **or** human-`descoped`. Independent code components may deliver
|
|
15
|
+
earlier, but the whole run does not finalize while one remains pending. Descoping is not
|
|
16
|
+
restricted by kind — `record-scope-decision` never restricted it, and `external-verification`,
|
|
17
|
+
the kind that exists for work no agent session can perform, is the one most likely to need it,
|
|
18
|
+
so refusing a descoped unit here left such a run with no reachable terminal state (#1087). It
|
|
19
|
+
is not a bypass either: the disposition is re-derived through `terminalDisposition()`, which
|
|
20
|
+
re-validates the whole scope decision, so a loop-applied, non-human, or delivery-claiming
|
|
21
|
+
"descope" leaves the unit pending and the run unfinalizable. `finalization.scope` counts
|
|
22
|
+
`descoped` separately from `complete`, and the handoff names each descoped unit and its reason.
|
|
23
|
+
3. The command freshly fetches `origin/<targetBranch>`. A canonical component delivery contributes one component merge-SHA ancestry claim regardless of member count; legacy unit delivery contributes its historical unit claim. Every claim must be an ancestor of that fetched ref. A merge command or cached boolean is not ancestry proof.
|
|
24
|
+
4. Unit issues and every recorded unit/component PR are read live. Delivered/prior-art
|
|
25
|
+
claims require terminal GitHub state; delivered component PRs must be merged at the
|
|
26
|
+
recorded SHA; a `closed-not-planned` human descope must be closed unmerged with the
|
|
27
|
+
matching decision record. Every returned observation must carry the exact positive
|
|
28
|
+
integer issue/PR number requested at the boundary. Missing, malformed, or mismatched
|
|
29
|
+
identities fail the attempt before persistence, and the requested number remains the
|
|
30
|
+
canonical identity in immutable evidence.
|
|
31
|
+
5. The checkout is restored to `originalBranch` without discarding local changes. The
|
|
32
|
+
workspace reap then removes only clean, published trees. A failed removal, an unreaped
|
|
33
|
+
clean tree, an unreadable tree, or preserved unpublished work blocks finalization and is
|
|
34
|
+
reported without deletion.
|
|
35
|
+
6. The final handoff is rendered from the validated record. It includes delivery, scope,
|
|
36
|
+
cleanup, deferrals/known debt, and autonomous breaker decisions.
|
|
37
|
+
|
|
38
|
+
## What the loop owes finalization
|
|
39
|
+
|
|
40
|
+
These are the loop’s obligations, and finalization cannot repair a missed one. Every `merge-ready` unit carries a terminal `delivery.outcome` — `merged` with a verified `mergedSha`, or `handed-back` quoting the blocking condition; **a unit with neither is reported *undelivered*, never as done**. An epic hands back **one deliverable per [component](deliverables.md#deliverables-the-shippable-component-not-the-whole-epic)**, and its exit gate is the closed-world ensure-coverage **audit** of the delivered tree against its source — the PRD/spec when one exists, **otherwise the epic issue's own body**, which is the spec when nothing else is. **Merge only what `mergeShippable` authorizes, only into `targetBranch`; never promote to production.** Push every unit branch **before** finalization. **Reap the workspaces last** — through `finalize`, after those pushes. **Never `--force` a worktree removal and never delete one by hand**: preserved unpublished work blocks finalization and stays on disk. On a `worktree` run the orchestrator's own checkout is removed separately, after the reap, and only once the finalization record exists.
|
|
41
|
+
|
|
42
|
+
## What the handoff shows, per unit
|
|
43
|
+
|
|
44
|
+
PR + branch (epic: one deliverable per [component](deliverables.md#deliverables-the-shippable-component-not-the-whole-epic) — its combined PR, or the merge SHA when `mergeShippable` merged it); the terminal `delivery.outcome`; CI status; the review verdict on the current HEAD with **review model and per-unit implementation model** (showing they differ) and every finding's resolution; the authoritative `contractRevision` SHA + refs, proof HEAD contains it, and `reviewedContractSha` equal to it; the checklist validate result plus any `Unverified`/quarantined rows with dated exits; hazard rows banked; known gaps as tracked issues.
|
|
45
|
+
|
|
46
|
+
Then the **round profile** from `rounds` — round count and per-round `at`/`scope` where recorded (both optional in `validateRoundLog`) for a delta-vs-full time read, the diff-derived `changedSurfaces` profile (`runtime|tests|verification-harness|evidence|docs|none`), each independent `reviewSubject`, and how many rounds re-raised a theme an earlier round had already named: the numbers that say whether the loop converged or circled. For rounds whose `reviewSubject` is `evidence`, `run-state.mjs evidence-audit <slug>` answers *what they were spent on* and therefore what to repair — read it as [run-state.md](run-state.md) describes, `sameHeadAsPrevious` before the count.
|
|
47
|
+
|
|
48
|
+
**Epic extras:** the roster, per-component integration verdicts, which components merged vs. handed back, the [decomposition gate](intake.md#intake--scheduling) re-run against the final roster, and the closed-world ensure-coverage audit that is the exit gate.
|
|
49
|
+
|
|
50
|
+
On success the command writes immutable `finalization` state and prints its `handoff`.
|
|
51
|
+
`run-state.mjs validate <slug>` recomputes the manifest-derived portions and rejects a
|
|
52
|
+
forged or stale record, including nonnumeric or mismatched persisted GitHub identities.
|
|
53
|
+
The complete candidate passes that same validator before the success write. A failed
|
|
54
|
+
attempt leaves no partial finalization, and a corrected rerun remains safe.
|
|
55
|
+
|
|
56
|
+
## Diagnostics are separate
|
|
57
|
+
|
|
58
|
+
`run-state.mjs postmortem <slug> [--json]` is an explicit, read-only diagnostic. It does
|
|
59
|
+
not run from `progress` or `finalize`, save a series, authorize completion, require finding
|
|
60
|
+
adjudication, or generate a process issue.
|
|
61
|
+
|
|
62
|
+
## What the handoff reports, per unit
|
|
63
|
+
|
|
64
|
+
Moved here from `SKILL.md` when that file was restored to an index. `finalize` generates this from
|
|
65
|
+
validated state — the list below is what to expect in it, and what a reader should check is present.
|
|
66
|
+
|
|
67
|
+
Per unit, with evidence: PR + branch (epic: **one deliverable per [component](deliverables.md#deliverables-the-shippable-component-not-the-whole-epic)** — its combined PR, or the merge SHA when `mergeShippable` merged it); **the canonical `components[].delivery.outcome` resolved through each member's `deliveryRef` — `merged` with the one verified component `mergedSha`, or `handed-back` with the condition that blocked it; a member with neither is reported *undelivered*, never as done** (older singleton/unit manifests retain the legacy `units[].delivery` read); CI status; the review verdict on the current HEAD with **review model and per-unit implementation model** (showing they differ) and every finding's resolution; the authoritative `contractRevision` SHA + refs, proof that HEAD contains it, and `reviewedContractSha` equal to it; checklist validate result + any `Unverified`/quarantined rows with dated exits; hazard rows banked; the **round profile** from `rounds` (round count and per-round `at`/`scope` where recorded (both optional in `validateRoundLog`) for a delta-vs-full time read, the diff-derived `changedSurfaces` profile (`runtime|tests|verification-harness|evidence|docs|none`) and each independent `reviewSubject`, and how many re-raised a theme an earlier round had already named — the numbers that say whether this loop is converging or circling); **`run-state.mjs evidence-audit <slug>` for rounds whose `reviewSubject` is `evidence`** — not how many, which the round profile already gives, but *what they were spent on* and therefore what to repair: a recurring **screened** class (`stale-locator`, `unrun-gate-row`, `stale-stamp`) means a screen this repo already has was skipped or run without `--diff`, and a recurring unscreened one (`contract-drift`, `checklist-row`) is the named incident a new screen would be added with. **Read its `sameHeadAsPrevious` before you read the count**: an evidence-subject round at the same HEAD as the round before it had no commit between them at all, so it is usually a double-record (one entry per loop *action* rather than per verdict) rather than a round bought on unmoved code — `epic-25-proposal-generator` read as 54% evidence rounds and was 15%. Its repair is `fix-the-recording`, and no screen, existing or new, would ever have caught it; known gaps as tracked issues. Epic extras: the roster, per-component integration verdicts, which components merged vs. handed back, the [decomposition gate](intake.md#intake--scheduling) re-run against the final roster, and a closed-world ensure-coverage **audit** of the delivered tree against the source — the PRD/spec when one exists, **otherwise the epic issue's own body**, which is the spec when nothing else is (that audit is the exit gate). **Merge only what `mergeShippable` authorizes, and only into `targetBranch`; never promote to production.** Push every unit branch before finalization. **Reap the workspaces last** through `finalize`, after those pushes; it restores the recorded branch and invokes the existing evidence-driven reap engine. **Never `--force` a worktree removal and never delete one by hand**: preserved unpublished work blocks finalization and stays on disk. On a `worktree` run, the **orchestrator's own checkout is removed separately, after the reap** and only after the successful finalization record exists.
|
|
68
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# The four guarantees, in full
|
|
2
|
+
|
|
3
|
+
The four bars are stated on [SKILL.md](../SKILL.md) and never move; this file is each one's operative detail — what it refuses, what satisfies it, and the state that records it. Each guarantee's incident record: [why.md](why.md#the-four-guarantees).
|
|
4
|
+
|
|
5
|
+
## The four guarantees
|
|
6
|
+
|
|
7
|
+
1. **Real tests, honestly green.** Never skip, guard, weaken or `.only` a test to pass; never mock a first-party internal seam or intercept first-party routes in a journey; an assertion against a 404/empty/error page is a defect. A missing precondition is the test's *arrange* step — **seed it**. Flaky → quarantine lane (runs, non-blocking, `Unverified`); obsolete → delete. Gate the net `merge-base...HEAD` diff.
|
|
8
|
+
2. **An independent review that actually ran.** Fresh context **and** a different model than the one that wrote the diff. The reviewer loads `review-pr` and returns its proof artifacts; a review-shaped prose answer does not count.
|
|
9
|
+
3. **The loop exits on a fresh verdict on the current authorization boundary, never on a claim.** "I addressed the findings" is not a terminal state. A unit PASS is terminal for that branch and becomes preserved **preliminary evidence** (its notes become `deferrals[]`, never another round). **Component delivery is authorized separately** ([delivery.md](delivery.md)): movement after its terminal PASS requires a typed `reopenReason: ci-red|head-rewritten|contract-revised|integration-finding|external-review`, a changed matching `ci|head|contract|integration` boundary, and a fresh freeze. A bar the orchestrator may raise after the fact is not a bar.
|
|
10
|
+
4. **Merging requires a recorded human authorization, and only ever targets the integration branch.** That authorization is `mergeShippable`, set only by a human answering pre-flight. With it, an [independently-shippable component](deliverables.md#deliverables-the-shippable-component-not-the-whole-epic) merges into `targetBranch` at its full bar; without it the loop hands components back merge-ready and merges nothing — never to production, which is `resolve-release`'s with its own authorization. Pre-flight *recommends* `autonomous`, but an **unset** field resolves to `supervised`: no recorded answer, no merge.
|