@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,417 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The release checkpoint summary: where this attempt actually is, rendered from the manifest at
|
|
3
|
+
// every step transition.
|
|
4
|
+
//
|
|
5
|
+
// Why it exists. A release is long, mostly waiting, and outward-facing at nearly every step, so the
|
|
6
|
+
// operator's question is always the same — what has actually happened to production, and what is
|
|
7
|
+
// owed next? In pi session 019faea6 the agent answered that well in prose, but ad hoc: a different
|
|
8
|
+
// shape each time, derived from whatever was in context rather than from recorded state. When the
|
|
9
|
+
// session eventually parked at `blocked-manual`, reconstructing what had reached production took
|
|
10
|
+
// reading the whole transcript.
|
|
11
|
+
//
|
|
12
|
+
// THE RULE THIS INHERITS FROM resolve-issues: a step is `done` only when the manifest carries the
|
|
13
|
+
// EVIDENCE for it, never because `step` has moved past it. `step` is progress and evidence is
|
|
14
|
+
// fact, and the gap between them is exactly where a release lies to itself — epic-986 recorded
|
|
15
|
+
// four units `merge-ready` with `mergedSha: null` and reported them as delivered. So here, "the
|
|
16
|
+
// candidate exists" is not `step === 'validate-candidate'`; it is a recorded attested identity
|
|
17
|
+
// tuple. A step whose marker has passed but whose evidence is missing renders `undelivered`, which
|
|
18
|
+
// is deliberately not a synonym for `done` — and where the manifest was never the home for that
|
|
19
|
+
// proof, `unrecorded` says so instead of manufacturing a defect (see the three-status note below).
|
|
20
|
+
//
|
|
21
|
+
// It is a pure function of the manifest. No reads, no network — the manifest is the audit trail,
|
|
22
|
+
// and a summary that consulted the world could disagree with the record it is supposed to be
|
|
23
|
+
// reporting.
|
|
24
|
+
|
|
25
|
+
// Every field name below is CANONICAL — it appears in this skill's own doctrine and in the
|
|
26
|
+
// manifest `run-state.mjs` validates. That is not a stylistic note; the first version of this
|
|
27
|
+
// ladder invented five (`candidateVerdict`, `servingRevision`, `trafficPercent`, `finalTag`,
|
|
28
|
+
// `promotionPr`), none of which any release records. Steps 4a, 4b and 5 could therefore never read
|
|
29
|
+
// `done`, so a perfectly successful release — tagged, shifted, verified — would have ended with
|
|
30
|
+
// this summary insisting three steps were still owed. A summary written to stop a release lying to
|
|
31
|
+
// itself would have lied in the opposite direction, and the noise is what gets a tool switched off.
|
|
32
|
+
//
|
|
33
|
+
// The tests did not catch it because they were self-consistent with the invention: they built
|
|
34
|
+
// manifests using the same made-up names the reader looked for. `field-names-are-canonical` below
|
|
35
|
+
// closes the class by checking the ladder against the doctrine rather than against my memory.
|
|
36
|
+
//
|
|
37
|
+
// THREE STATUSES, NOT TWO. `undelivered` means "this step should have recorded evidence and did
|
|
38
|
+
// not" — a defect. `unrecorded` means "the manifest is not where this step's proof lives" — not a
|
|
39
|
+
// defect, and conflating them is what produced the false alarm above. Step 4a's ALIVE verdict and
|
|
40
|
+
// step 4b's post-shift health live in the durable evidence bundle and in `smoke-verdict.json`, so
|
|
41
|
+
// the manifest genuinely cannot answer for them; the summary says where to look instead of
|
|
42
|
+
// pretending the step failed.
|
|
43
|
+
|
|
44
|
+
import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
|
|
45
|
+
import { isFinalizedVerification } from './finalize-release.mjs'
|
|
46
|
+
import { METADATA_SYNC_SOURCE, metadataPrStatus } from './metadata-pr-status.mjs'
|
|
47
|
+
import {
|
|
48
|
+
CANONICAL_RELEASE_MANIFEST_FIELDS,
|
|
49
|
+
CANONICAL_RELEASE_FIELDS as CONTRACT_RELEASE_FIELDS,
|
|
50
|
+
classifyReleaseManifest,
|
|
51
|
+
normalizeReleaseVerdict,
|
|
52
|
+
} from '../../resolve-issues/scripts/release-state-contract.mjs'
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
export { metadataPrStatus } from './metadata-pr-status.mjs'
|
|
56
|
+
export const checkpointReleaseState = classifyReleaseManifest
|
|
57
|
+
|
|
58
|
+
export const STEPS = [
|
|
59
|
+
{
|
|
60
|
+
id: 'preflight',
|
|
61
|
+
label: 'Pre-flight — probes + authorization envelope',
|
|
62
|
+
// `envelope` is a manifest-level field run-state validates, not a release.* one.
|
|
63
|
+
evidence: (r, m) => (m.envelope && Object.keys(m.envelope).length > 0 ? 'envelope recorded' : null),
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: 'assemble',
|
|
67
|
+
label: 'Steps 0-2 — intake, assemble, promotion PR',
|
|
68
|
+
// `cutCommit` is the recorded artifact of step 1b. Under the trunk + merge-queue topology step
|
|
69
|
+
// 1 assembles nothing and there is no cut commit, which is why an absence here is `unrecorded`
|
|
70
|
+
// rather than a defect — the topology decides whether this step had anything to record.
|
|
71
|
+
// In queue/verified-sha-github-flow modes, the selected eligible SHA plus the recorded
|
|
72
|
+
// release-readiness checklist is the equivalent evidence (#818).
|
|
73
|
+
evidence: (r) => {
|
|
74
|
+
if (r.cutCommit) return `cut commit ${short(r.cutCommit)}`
|
|
75
|
+
if (r.candidateSha && hasReleaseReadiness(r)) {
|
|
76
|
+
return `selected SHA ${short(r.candidateSha)}; release readiness recorded`
|
|
77
|
+
}
|
|
78
|
+
return null
|
|
79
|
+
},
|
|
80
|
+
unrecordedWhen: (r, m) => {
|
|
81
|
+
if (r.cutCommit) return false
|
|
82
|
+
if (r.candidateSha && hasReleaseReadiness(r)) return false
|
|
83
|
+
return isNoCutTopology(m)
|
|
84
|
+
},
|
|
85
|
+
unrecordedNote: 'no cut commit — expected under trunk + merge-queue / verified-sha-github-flow, where step 1 assembles nothing; GitFlow owes a cut commit',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: 'candidate',
|
|
89
|
+
label: 'Step 3 — promote, build candidate at 0% traffic',
|
|
90
|
+
// The identity tuple, not the revision name: a revision name says where to look, the tuple
|
|
91
|
+
// says what is running there. Principle 12's whole point.
|
|
92
|
+
evidence: (r) => {
|
|
93
|
+
const id = r.candidateIdentity
|
|
94
|
+
if (id && id.sourceSha && id.revision) return `candidate ${id.revision} @ ${short(id.sourceSha)}${id.imageDigestSource ? ` (${id.imageDigestSource})` : ''}`
|
|
95
|
+
return null // a candidateRevision with no attested identity is not evidence
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: 'validate-candidate',
|
|
100
|
+
label: 'Step 4a — validate the candidate (read-only, pre-exposure)',
|
|
101
|
+
// The ALIVE/DEAD verdict is `smoke-verdict.json` plus the evidence bundle — deliberately not a
|
|
102
|
+
// manifest field, because `green-gate.mjs shift` reads the artifact so that "on that exact
|
|
103
|
+
// candidate" stays a comparison rather than a manifest assertion. When the manifest does carry
|
|
104
|
+
// a `candidateVerdict`, render it as the pointer to the artifact rather than leaving the step
|
|
105
|
+
// unrecorded (#818).
|
|
106
|
+
evidence: (r) => {
|
|
107
|
+
const v = normalizeReleaseVerdict(r.candidateVerdict)
|
|
108
|
+
if (!v || typeof v !== 'object') return null
|
|
109
|
+
// The required evidence tuple is the same for ALIVE and DEAD: state plus the
|
|
110
|
+
// artifact path, the generation time, and the target that was probed. All three
|
|
111
|
+
// must be non-empty strings; truthy object values rendered as [object Object] and
|
|
112
|
+
// let malformed records pass as done (#818 review finding).
|
|
113
|
+
if (v.state === 'ALIVE' && isNonEmptyString(v.artifactPath) && isNonEmptyString(v.generatedAt) && isNonEmptyString(v.target)) {
|
|
114
|
+
return `ALIVE at ${v.target} (${v.generatedAt}) — artifact ${v.artifactPath}`
|
|
115
|
+
}
|
|
116
|
+
if (v.state === 'DEAD' && isNonEmptyString(v.artifactPath) && isNonEmptyString(v.generatedAt) && isNonEmptyString(v.target)) {
|
|
117
|
+
return `DEAD — artifact ${v.artifactPath} at ${v.target} (${v.generatedAt})`
|
|
118
|
+
}
|
|
119
|
+
return null
|
|
120
|
+
},
|
|
121
|
+
unrecordedWhen: (r) => !r.candidateVerdict || typeof r.candidateVerdict !== 'object',
|
|
122
|
+
unrecordedNote: 'the ALIVE verdict lives in smoke-verdict.json and the evidence bundle, not the manifest',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
id: 'expose',
|
|
126
|
+
label: 'Step 4b — shift traffic, confirm the serving revision',
|
|
127
|
+
// `recheckFence` is the canonical record of the pre-shift re-check. It is evidence the fence
|
|
128
|
+
// ran, which is the manifest's part; the post-shift serving confirmation is bundle evidence.
|
|
129
|
+
// Where durable processing was declared, `quiescence.servingRevisionAtResume` is the one
|
|
130
|
+
// serving read the manifest does carry.
|
|
131
|
+
evidence: (r) => {
|
|
132
|
+
const resumed = r.quiescence && r.quiescence.servingRevisionAtResume
|
|
133
|
+
if (resumed) return `fence recorded; serving ${resumed} at resume`
|
|
134
|
+
if (r.recheckFence) return 'pre-shift re-check fence recorded'
|
|
135
|
+
return null
|
|
136
|
+
},
|
|
137
|
+
unrecordedWhen: (r) => !r.recheckFence && !(r.quiescence && r.quiescence.servingRevisionAtResume),
|
|
138
|
+
unrecordedNote: 'no re-check fence recorded — if traffic shifted, the post-shift confirmation is in the evidence bundle',
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
id: 'verify',
|
|
142
|
+
label: 'Step 5 — route on the verdict, tag, publish, back-merge',
|
|
143
|
+
// The attempt reaching `released` is the lease CLOSE, not the terminal record — #963's
|
|
144
|
+
// finalizer owns the one durable transition that assembles the top-level `verification`
|
|
145
|
+
// block and advances `step` to done, and step 5 reads done only once that transition is
|
|
146
|
+
// recorded. The verification must be the shape the finalizer writes (isFinalizedVerification
|
|
147
|
+
// — finalizedBy + finalizedAt + the six required observations), never merely a non-null
|
|
148
|
+
// object: a hand-assembled `{}` rendering the release complete here while the finalizer
|
|
149
|
+
// refused it was the release-finalization-terminal-proof finding. A released attempt still
|
|
150
|
+
// sitting at `verify` is the Forex v0.1.12 shape: the lease freed while the resume key said
|
|
151
|
+
// mid-machine, and rendering it done here is what let the checkpoint claim a finished
|
|
152
|
+
// release the manifest could not prove. `backMerge` is the GitFlow-only follow-on and is
|
|
153
|
+
// reported when present rather than required.
|
|
154
|
+
evidence: (r, m) => {
|
|
155
|
+
if (r.attempt && r.attempt.state === 'released'
|
|
156
|
+
&& m.step === 'done' && isFinalizedVerification(m.verification)) {
|
|
157
|
+
return `attempt released${r.backMerge ? ' (back-merge recorded)' : ''}`
|
|
158
|
+
}
|
|
159
|
+
return null
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
// Canonical `release.*` field names this ladder is allowed to read. Kept beside the ladder so the
|
|
165
|
+
// guard test has one list to check against, and so adding a reader forces a decision about whether
|
|
166
|
+
// the field is real. Sourced from this skill's references and from run-state.mjs's validation.
|
|
167
|
+
export const CANONICAL_RELEASE_FIELDS = CONTRACT_RELEASE_FIELDS
|
|
168
|
+
|
|
169
|
+
// Deploy-trigger resolution order for the checkpoint line. attempt and envelope.deployTrigger
|
|
170
|
+
// are the declared homes; envelope.version.deployTrigger is what identity-v0.4.1 actually
|
|
171
|
+
// recorded (the version plan nests the shape), and missing that path printed `(undeclared)`
|
|
172
|
+
// while the envelope carried `rc-tag` (#800).
|
|
173
|
+
export function resolveDeployTrigger(manifest) {
|
|
174
|
+
const m = manifest || {}
|
|
175
|
+
const r = m.release || {}
|
|
176
|
+
const attempt = r.attempt || {}
|
|
177
|
+
const envelope = m.envelope || {}
|
|
178
|
+
const version = envelope.version && typeof envelope.version === 'object' ? envelope.version : null
|
|
179
|
+
return attempt.deployTrigger
|
|
180
|
+
|| envelope.deployTrigger
|
|
181
|
+
|| (version && version.deployTrigger)
|
|
182
|
+
|| null
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Metadata-PR completeness lives in metadata-pr-status.mjs so postmortem.mjs can use it
|
|
186
|
+
// without importing this module (report.mjs dynamically imports postmortem.mjs).
|
|
187
|
+
|
|
188
|
+
// ensure-target-green (#807) — tip check-runs repair phase. Surfaces time spent and outcome
|
|
189
|
+
// on the checkpoint so a release that spent N minutes repairing tip is visible, not buried.
|
|
190
|
+
export function ensureGreenStatus(release) {
|
|
191
|
+
const eg = release && release.ensureGreen
|
|
192
|
+
if (!eg || typeof eg !== 'object') return null
|
|
193
|
+
const outcome = eg.outcome || '(unknown)'
|
|
194
|
+
const head = eg.finalHead ? String(eg.finalHead).slice(0, 8) : '(none)'
|
|
195
|
+
const ms = Number.isFinite(eg.durationMs) ? eg.durationMs : null
|
|
196
|
+
const mins = ms != null ? `${Math.round(ms / 60000)}m` : null
|
|
197
|
+
const classes = Array.isArray(eg.failingClasses) && eg.failingClasses.length
|
|
198
|
+
? ` classes=[${eg.failingClasses.join(',')}]`
|
|
199
|
+
: ''
|
|
200
|
+
const time = mins != null ? ` · ${mins}` : ''
|
|
201
|
+
return { line: `ensure-green: ${outcome} @ ${head}${time}${classes}` }
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Manifest-level fields, from `run-state.mjs`'s own validation. Guarded for the same reason as the
|
|
205
|
+
// release list: `m.slug` was read here for the report title and no manifest has ever carried it —
|
|
206
|
+
// the field is `runSlug` — so every summary would have fallen through to "(unnamed release)".
|
|
207
|
+
export const CANONICAL_MANIFEST_FIELDS = CANONICAL_RELEASE_MANIFEST_FIELDS
|
|
208
|
+
|
|
209
|
+
const short = (sha) => String(sha || '').slice(0, 8)
|
|
210
|
+
|
|
211
|
+
function isNonEmptyString(value) {
|
|
212
|
+
return typeof value === 'string' && value.trim().length > 0
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function hasReleaseReadiness(release) {
|
|
216
|
+
return Array.isArray(release && release.releaseReadiness) && release.releaseReadiness.length > 0
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function isNoCutTopology(manifest) {
|
|
220
|
+
const m = manifest || {}
|
|
221
|
+
return m.deliveryMode === 'queue' || (m.envelope && m.envelope.mode === 'verified-sha-github-flow')
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Terminal attempt states, and whether each one still holds the lease. `blocked-manual` is
|
|
225
|
+
// terminal-VALUED but holds it — a release parked on a human is still in flight, and rendering it
|
|
226
|
+
// as finished is how a second release starts on top of the first.
|
|
227
|
+
const ATTEMPT_STATES = {
|
|
228
|
+
open: { holds: true, note: 'in flight' },
|
|
229
|
+
released: { holds: false, note: 'released' },
|
|
230
|
+
'failed-pre-promotion': { holds: false, note: 'failed before promotion — nothing exposed' },
|
|
231
|
+
'rolled-back': { holds: false, note: 'rolled back' },
|
|
232
|
+
revoked: { holds: false, note: 'revoked (rc tag retained — tags are immutable)' },
|
|
233
|
+
'blocked-manual': { holds: true, note: 'parked on a human — STILL HOLDS THE LEASE' },
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export function stepStatuses(manifest) {
|
|
237
|
+
const m = manifest || {}
|
|
238
|
+
const r = m.release || {}
|
|
239
|
+
const currentIndex = STEPS.findIndex((s) => s.id === m.step)
|
|
240
|
+
return STEPS.map((step, i) => {
|
|
241
|
+
const evidence = step.evidence(r, m) || null
|
|
242
|
+
const unrecorded = !evidence && typeof step.unrecordedWhen === 'function' && step.unrecordedWhen(r, m)
|
|
243
|
+
let status
|
|
244
|
+
if (evidence) status = 'done'
|
|
245
|
+
// `unrecorded` outranks `undelivered` for a passed step: the manifest was never the place this
|
|
246
|
+
// proof lived, so calling it a defect is a false alarm — and a summary that cries wolf on a
|
|
247
|
+
// healthy release is one nobody reads by the third time.
|
|
248
|
+
else if (currentIndex >= 0 && i < currentIndex) status = unrecorded ? 'unrecorded' : 'undelivered'
|
|
249
|
+
else if (currentIndex >= 0 && i === currentIndex) status = 'current'
|
|
250
|
+
else status = 'pending'
|
|
251
|
+
return { id: step.id, label: step.label, status, evidence, note: unrecorded ? step.unrecordedNote : null }
|
|
252
|
+
})
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const MARK = { done: '[x]', current: '[>]', undelivered: '[!]', unrecorded: '[~]', pending: '[ ]' }
|
|
256
|
+
|
|
257
|
+
export function renderCheckpoint(manifest) {
|
|
258
|
+
const m = manifest || {}
|
|
259
|
+
const r = m.release || {}
|
|
260
|
+
const attempt = r.attempt || {}
|
|
261
|
+
const state = ATTEMPT_STATES[attempt.state] || null
|
|
262
|
+
const statuses = stepStatuses(m)
|
|
263
|
+
const lines = []
|
|
264
|
+
|
|
265
|
+
lines.push(`## Release checkpoint — ${m.runSlug || (r.versionPlan && r.versionPlan.nextVersion) || '(unnamed release)'}`)
|
|
266
|
+
lines.push('')
|
|
267
|
+
lines.push(`- attempt: \`${attempt.id || '(none)'}\` — ${attempt.state || '(no state)'}${state ? ` (${state.note})` : ''}`)
|
|
268
|
+
lines.push(`- lease: ${state ? (state.holds ? '**HELD**' : 'free') : '**UNKNOWN — treat as held**'}`)
|
|
269
|
+
const deployTrigger = resolveDeployTrigger(m)
|
|
270
|
+
lines.push(`- step: \`${m.step || '(none)'}\` · deploy trigger: \`${deployTrigger || '(undeclared)'}\``)
|
|
271
|
+
if (r.rcTag) lines.push(`- rc tag: \`${r.rcTag}\``)
|
|
272
|
+
const meta = metadataPrStatus(r)
|
|
273
|
+
if (meta) lines.push(`- ${meta.line}`)
|
|
274
|
+
const ensureGreen = ensureGreenStatus(r)
|
|
275
|
+
if (ensureGreen) lines.push(`- ${ensureGreen.line}`)
|
|
276
|
+
lines.push('')
|
|
277
|
+
|
|
278
|
+
for (const s of statuses) {
|
|
279
|
+
const suffix = s.evidence ? ` — ${s.evidence}`
|
|
280
|
+
: s.status === 'undelivered' ? ' — **step passed with no evidence recorded — NOT done**'
|
|
281
|
+
: s.status === 'unrecorded' ? ` — not manifest-tracked: ${s.note}`
|
|
282
|
+
: ''
|
|
283
|
+
lines.push(`${MARK[s.status]} ${s.label}${suffix}`)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// What production is carrying right now, stated separately from progress. Between step 3 and the
|
|
287
|
+
// shift there is a revision no user reaches, and if the session dies only the manifest says it
|
|
288
|
+
// exists — so it is named even when nothing has been exposed.
|
|
289
|
+
lines.push('')
|
|
290
|
+
lines.push('**Production right now:**')
|
|
291
|
+
// Which revision is serving is INFERRED from the attempt's own terminal state, not read from a
|
|
292
|
+
// field — there is no `release.servingRevision`, and inventing one is what made the first version
|
|
293
|
+
// of this file unusable. The inference is stated so a reader can disbelieve it: `released` means
|
|
294
|
+
// the shift completed and the candidate is serving, `rolled-back` means it is not, and any other
|
|
295
|
+
// state means traffic never moved. Where the manifest carries a real post-resume serving read
|
|
296
|
+
// (`quiescence.servingRevisionAtResume`), that observation wins over any inference.
|
|
297
|
+
const observedServing = r.quiescence && r.quiescence.servingRevisionAtResume
|
|
298
|
+
const attemptState = attempt.state
|
|
299
|
+
if (observedServing) {
|
|
300
|
+
lines.push(`- serving: \`${observedServing}\` (observed at resume)`)
|
|
301
|
+
} else if (attemptState === 'released' && (r.candidateRevision || (r.candidateIdentity && r.candidateIdentity.revision))) {
|
|
302
|
+
lines.push(`- serving: \`${r.candidateRevision || r.candidateIdentity.revision}\` (inferred from attempt \`released\`)`)
|
|
303
|
+
} else if (r.previousRevision) {
|
|
304
|
+
lines.push(`- serving: \`${r.previousRevision}\` (incumbent — traffic has not moved${attemptState === 'rolled-back' ? ', restored by rollback' : ''})`)
|
|
305
|
+
} else {
|
|
306
|
+
lines.push('- serving: (not recorded)')
|
|
307
|
+
}
|
|
308
|
+
if (r.candidateRevision) {
|
|
309
|
+
const exposed = attemptState === 'released'
|
|
310
|
+
lines.push(`- candidate: \`${r.candidateRevision}\`${exposed ? ' (exposed)' : ' — at 0% traffic, reached by nobody'}${r.candidateIdentity ? '' : ' — **no attested identity recorded**'}`)
|
|
311
|
+
}
|
|
312
|
+
if (r.quiescence) {
|
|
313
|
+
lines.push(`- durable processing: paused=${!!r.quiescence.pausedAt} resumed=${!!r.quiescence.resumedAt}${r.quiescence.pausedAt && !r.quiescence.resumedAt ? ' — **PAUSED AND NOT RESUMED**' : ''}`)
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Only `undelivered` is owed. Counting `unrecorded` here is precisely the false alarm that made
|
|
317
|
+
// the first version of this summary unusable on a successful release.
|
|
318
|
+
const undelivered = statuses.filter((s) => s.status === 'undelivered')
|
|
319
|
+
const next = statuses.find((s) => s.status === 'current') || statuses.find((s) => s.status === 'pending')
|
|
320
|
+
lines.push('')
|
|
321
|
+
if (undelivered.length > 0) {
|
|
322
|
+
lines.push(`**Owed:** ${undelivered.length} step(s) passed without recording their evidence — ${undelivered.map((s) => s.id).join(', ')}. Record it or re-run them; the handoff must not report these as done.`)
|
|
323
|
+
}
|
|
324
|
+
lines.push(`**Next:** ${next ? next.label : 'nothing — every step has its evidence'}`)
|
|
325
|
+
return lines.join('\n')
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (isMainModule(import.meta.url)) {
|
|
329
|
+
const path = process.argv[2]
|
|
330
|
+
const flags = new Set(process.argv.slice(3))
|
|
331
|
+
if (!path) {
|
|
332
|
+
console.error('usage: report.mjs <run-manifest.json> [--postmortem] [--issue] [--no-save]\n\n'
|
|
333
|
+
+ 'Renders the release checkpoint summary. A step is `done` only when the manifest carries its\n'
|
|
334
|
+
+ 'evidence — `step` moving past it is not enough.\n\n'
|
|
335
|
+
+ 'The post-mortem is computed and SAVED automatically once the release reaches a terminal step\n'
|
|
336
|
+
+ '(done | discard | rollback). --postmortem prints it on demand, which is the only way to see\n'
|
|
337
|
+
+ 'the profile of a release that STALLED — a stall is itself one of its findings.\n\n'
|
|
338
|
+
+ 'When the manifest names a version and `durableEvidenceDir`, the VERSION-LEVEL post-mortem\n'
|
|
339
|
+
+ '(#961) is computed, printed and saved alongside: the aggregate of every durable evidence\n'
|
|
340
|
+
+ 'bundle the version left behind, across all of its attempts.')
|
|
341
|
+
process.exitCode = 2
|
|
342
|
+
} else {
|
|
343
|
+
const { readFileSync } = await import('node:fs')
|
|
344
|
+
const manifest = JSON.parse(readFileSync(path, 'utf8'))
|
|
345
|
+
const pm = await import('./postmortem.mjs')
|
|
346
|
+
|
|
347
|
+
// The version-level half (#961). The run-level pass profiles ONE manifest's record; this one
|
|
348
|
+
// aggregates every durable bundle the VERSION left behind, across all of its attempts — the
|
|
349
|
+
// shape a single-manifest pass cannot see (Forex v0.1.12: nine attempts, one repeated owner).
|
|
350
|
+
// Possible only when the manifest names both the version and the durable evidence dir; absent
|
|
351
|
+
// either, the run-level pass stands alone and nothing is invented. Returns null silently then,
|
|
352
|
+
// or { error } when the dir could not be read — a degraded report, never a failed handoff.
|
|
353
|
+
const versionLevel = async () => {
|
|
354
|
+
const version = pm.releaseVersion(manifest)
|
|
355
|
+
if (!isNonEmptyString(version) || !isNonEmptyString(manifest.durableEvidenceDir)) return null
|
|
356
|
+
const vpm = await import('./version-postmortem.mjs')
|
|
357
|
+
try {
|
|
358
|
+
return { profile: vpm.versionPostmortem({ dir: manifest.durableEvidenceDir, version, runSlug: manifest.runSlug }), vpm }
|
|
359
|
+
} catch (e) {
|
|
360
|
+
return { error: e?.message ?? String(e) }
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
// Print the attempt table + summary, and save into the shared series on the same terms as the
|
|
364
|
+
// run-level save. An aggregate that found NO bundles is reported but not persisted — an empty
|
|
365
|
+
// discovery is a statement about the dir, not a measurement of the version.
|
|
366
|
+
const versionReport = async ({ save }) => {
|
|
367
|
+
const vl = await versionLevel()
|
|
368
|
+
if (!vl) return
|
|
369
|
+
if (vl.error) {
|
|
370
|
+
console.error(`warn: version-level post-mortem could not be computed — ${vl.error}`)
|
|
371
|
+
return
|
|
372
|
+
}
|
|
373
|
+
const { profile: vp, vpm } = vl
|
|
374
|
+
if (!vp.attempts.length) {
|
|
375
|
+
console.log(`\nVERSION POST-MORTEM — no durable bundles found for ${vp.metrics.version} in ${manifest.durableEvidenceDir}`)
|
|
376
|
+
return
|
|
377
|
+
}
|
|
378
|
+
process.stdout.write(`\nVERSION POST-MORTEM — ${vp.metrics.version} across ${vp.metrics.attempts} attempt(s)\n`)
|
|
379
|
+
process.stdout.write(vpm.renderVersionPostmortem(vp))
|
|
380
|
+
if (save) {
|
|
381
|
+
const written = vpm.saveVersionPostmortem(vp)
|
|
382
|
+
if (written.saved) process.stdout.write(` saved: ${written.paths.json}\n series: ${written.paths.index}\n`)
|
|
383
|
+
else console.error(`warn: version-level post-mortem computed but NOT saved — ${written.error}`)
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (flags.has('--issue')) {
|
|
388
|
+
console.log(JSON.stringify(pm.renderReleasePostmortemIssue(manifest), null, 2))
|
|
389
|
+
} else if (flags.has('--postmortem')) {
|
|
390
|
+
process.stdout.write(pm.renderReleasePostmortem(manifest))
|
|
391
|
+
await versionReport({ save: !flags.has('--no-save') })
|
|
392
|
+
if (!flags.has('--no-save')) {
|
|
393
|
+
// NOT named `r`: that identifier is the release block everywhere else in this module,
|
|
394
|
+
// and report.test.mjs scans the source for `r.<field>` reads to catch invented
|
|
395
|
+
// release fields. Shadowing it would have made this code look like three of them.
|
|
396
|
+
const written = pm.saveReleasePostmortem(manifest)
|
|
397
|
+
if (written.saved) process.stdout.write(`\n saved: ${written.paths.json}\n series: ${written.paths.index}\n`)
|
|
398
|
+
else console.error(`warn: post-mortem computed but NOT saved — ${written.error}`)
|
|
399
|
+
}
|
|
400
|
+
} else {
|
|
401
|
+
console.log(renderCheckpoint(manifest))
|
|
402
|
+
// The automatic half. This script is run at EVERY step transition (SKILL.md § The
|
|
403
|
+
// release loop), so hanging the save on the terminal one makes the pass mandatory in
|
|
404
|
+
// practice rather than in prose — the same move as `progress` in the delivery lane.
|
|
405
|
+
if (pm.releaseIsTerminal(manifest) && !flags.has('--no-save')) {
|
|
406
|
+
const written = pm.saveReleasePostmortem(manifest)
|
|
407
|
+
if (written.saved) {
|
|
408
|
+
const n = pm.releaseProfile(manifest).findings.length
|
|
409
|
+
console.log(`\nPOST-MORTEM saved — ${written.paths.json}\n ${n} finding(s). Read it: report.mjs ${path} --postmortem`)
|
|
410
|
+
} else {
|
|
411
|
+
console.error(`warn: release terminal but the post-mortem could not be saved — ${written.error}`)
|
|
412
|
+
}
|
|
413
|
+
await versionReport({ save: true })
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Re-probe the credential that performs step-4b platform reads.
|
|
3
|
+
//
|
|
4
|
+
// Pre-flight item 0 already runs this probe before the release opens, but the credential can
|
|
5
|
+
// expire *between* the 4a validation and the traffic shift (pi session 019faea6: gcloud reauth
|
|
6
|
+
// expired after the rc tag was pushed, leaving forty minutes of failed Cloud Run reads). This
|
|
7
|
+
// script is the same probe, available as a stand-alone command so step 4b and any resume at
|
|
8
|
+
// `validate`/`expose` can re-run it without re-running the whole pre-flight set.
|
|
9
|
+
//
|
|
10
|
+
// Fail closed: exit 0 only when the credential is live. A BLOCKED or UNKNOWN result exits 1
|
|
11
|
+
// with the same remedy detail as pre-flight item 0, so the operator sees the same fix path.
|
|
12
|
+
import { classifyCredential, DEFAULT_CREDENTIAL_COMMAND, sh } from './preflight-probes.mjs'
|
|
13
|
+
import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
|
|
14
|
+
|
|
15
|
+
export function evaluateCredential(command = DEFAULT_CREDENTIAL_COMMAND, timeout = 60_000) {
|
|
16
|
+
const result = sh(command, timeout)
|
|
17
|
+
return classifyCredential(result)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function takeValue(argv, i, flagName, args, key) {
|
|
21
|
+
const val = argv[++i]
|
|
22
|
+
if (val === undefined || val.startsWith('-')) {
|
|
23
|
+
if (val !== undefined) i-- // push flag-like token back so it is parsed as a flag/unknown
|
|
24
|
+
args.missing.push(flagName)
|
|
25
|
+
return i
|
|
26
|
+
}
|
|
27
|
+
args[key] = val
|
|
28
|
+
return i
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function takeNumber(argv, i, flagName, args, key) {
|
|
32
|
+
const val = argv[++i]
|
|
33
|
+
if (val === undefined || val.startsWith('-')) {
|
|
34
|
+
if (val !== undefined) i--
|
|
35
|
+
args.missing.push(flagName)
|
|
36
|
+
return i
|
|
37
|
+
}
|
|
38
|
+
const n = Number(val)
|
|
39
|
+
if (!Number.isFinite(n)) {
|
|
40
|
+
args.missing.push(flagName)
|
|
41
|
+
return i
|
|
42
|
+
}
|
|
43
|
+
args[key] = n
|
|
44
|
+
return i
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function parseArgs(argv) {
|
|
48
|
+
const args = { timeoutSeconds: 60, unknown: [], missing: [] }
|
|
49
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
50
|
+
const a = argv[i]
|
|
51
|
+
if (a === '--command') { args.commandProvided = true; i = takeValue(argv, i, '--command', args, 'command') }
|
|
52
|
+
else if (a === '--timeout') i = takeNumber(argv, i, '--timeout', args, 'timeoutSeconds')
|
|
53
|
+
else if (a === '--json') args.json = true
|
|
54
|
+
else if (a === '--help' || a === '-h') args.help = true
|
|
55
|
+
else if (a !== undefined) args.unknown.push(a)
|
|
56
|
+
}
|
|
57
|
+
return args
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function help() {
|
|
61
|
+
return `reprobe-credentials — re-probe the credential that performs step-4b platform reads.
|
|
62
|
+
|
|
63
|
+
Usage:
|
|
64
|
+
reprobe-credentials [--command <cmd>] [--timeout <seconds>] [--json]
|
|
65
|
+
|
|
66
|
+
Options:
|
|
67
|
+
--command <cmd> credential liveness probe (default: ${DEFAULT_CREDENTIAL_COMMAND})
|
|
68
|
+
--timeout <sec> probe timeout in seconds (default: 60)
|
|
69
|
+
--json machine-readable summary on stdout
|
|
70
|
+
|
|
71
|
+
Exit codes:
|
|
72
|
+
0 credential is live
|
|
73
|
+
1 credential blocked/unknown/expired — apply the remedy printed, then re-run
|
|
74
|
+
2 usage error
|
|
75
|
+
|
|
76
|
+
This is the same probe preflight-probes.mjs item 0 runs. Run it at the start of
|
|
77
|
+
step 4b and on resume when step is validate or expose, before any pause or shift.`
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function main(argv) {
|
|
81
|
+
const args = parseArgs(argv)
|
|
82
|
+
if (args.help) {
|
|
83
|
+
console.log(help())
|
|
84
|
+
return 0
|
|
85
|
+
}
|
|
86
|
+
if (args.unknown.length > 0) {
|
|
87
|
+
console.error(`reprobe-credentials: unknown argument(s): ${args.unknown.join(', ')}`)
|
|
88
|
+
return 2
|
|
89
|
+
}
|
|
90
|
+
if (args.missing.length > 0) {
|
|
91
|
+
console.error(`reprobe-credentials: missing or invalid value for: ${args.missing.join(', ')}`)
|
|
92
|
+
return 2
|
|
93
|
+
}
|
|
94
|
+
if (!Number.isFinite(args.timeoutSeconds) || args.timeoutSeconds <= 0) {
|
|
95
|
+
console.error('reprobe-credentials: --timeout must be a positive number')
|
|
96
|
+
return 2
|
|
97
|
+
}
|
|
98
|
+
const command = args.command || DEFAULT_CREDENTIAL_COMMAND
|
|
99
|
+
const probe = evaluateCredential(command, args.timeoutSeconds * 1000)
|
|
100
|
+
|
|
101
|
+
if (args.json) {
|
|
102
|
+
console.log(JSON.stringify(probe, null, 2))
|
|
103
|
+
} else {
|
|
104
|
+
console.log(`${probe.state.toUpperCase()} — ${probe.detail}`)
|
|
105
|
+
if (probe.remedy && probe.state !== 'ok') {
|
|
106
|
+
console.log(`remedy: ${probe.remedy}`)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return probe.state === 'ok' ? 0 : 1
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (isMainModule(import.meta.url)) {
|
|
113
|
+
process.exitCode = main(process.argv.slice(2))
|
|
114
|
+
}
|