@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,381 @@
|
|
|
1
|
+
// The release lane's post-mortem: what this release left behind, and what to change.
|
|
2
|
+
//
|
|
3
|
+
// MANDATORY and AUTOMATIC, on the same terms as the delivery lane's — `report.mjs` saves it
|
|
4
|
+
// when a release reaches a terminal step, and the value is the CROSS-RUN series. It shares
|
|
5
|
+
// that series, its renderer and its persistence with `resolve-issues`; only the questions
|
|
6
|
+
// differ, and they differ a lot.
|
|
7
|
+
//
|
|
8
|
+
// WHAT THIS PASS IS FOR, AND WHY IT IS NOT A SPEED PASS. The delivery lane's post-mortem
|
|
9
|
+
// hunts wasted wall-clock, because that is what an epic loses. A release does not — the
|
|
10
|
+
// measured median is well under an hour, since the lane is mostly waiting on watchers. What
|
|
11
|
+
// a release loses is not time but ACCOUNT: the record of what happened to production. So
|
|
12
|
+
// every finder below asks a completeness question, and the severities are about how much of
|
|
13
|
+
// a release's own history is unreachable from state, not about how long it took.
|
|
14
|
+
//
|
|
15
|
+
// **The corpus measurements live in one place: `references/postmortem.md`.** Each finder was
|
|
16
|
+
// added with the count of real releases it would have caught, and that table is dated and
|
|
17
|
+
// re-measurable. They are deliberately NOT restated here or in the strings this module
|
|
18
|
+
// renders: a number quoted in four files is a number that goes stale in three of them, which
|
|
19
|
+
// is the exact failure the delivery lane's `inFlightCap` finding exists because of (a default
|
|
20
|
+
// documented as 2 for nine days after it became 4). Read the table there before editing a
|
|
21
|
+
// severity or a threshold — the thresholds below are derived from it.
|
|
22
|
+
//
|
|
23
|
+
// Rollbacks and burned versions are reported as facts rather than faulted: a rollback that
|
|
24
|
+
// happened and was recorded is the machine WORKING, and a finder that scolds for it would
|
|
25
|
+
// train the reader to ignore the pass.
|
|
26
|
+
|
|
27
|
+
import {
|
|
28
|
+
profile, renderProfile, renderProfileIssue, saveProfile,
|
|
29
|
+
} from '../../resolve-issues/scripts/postmortem.mjs'
|
|
30
|
+
import {
|
|
31
|
+
CANONICAL_RELEASE_MANIFEST_FIELDS,
|
|
32
|
+
RELEASE_STEPS,
|
|
33
|
+
classifyReleaseManifest,
|
|
34
|
+
RELEASE_TERMINAL_STEPS,
|
|
35
|
+
validateReleaseHistory,
|
|
36
|
+
} from '../../resolve-issues/scripts/release-state-contract.mjs'
|
|
37
|
+
import { metadataPrStatus } from './metadata-pr-status.mjs'
|
|
38
|
+
|
|
39
|
+
const isObject = (v) => v != null && typeof v === 'object' && !Array.isArray(v)
|
|
40
|
+
const nonEmpty = (v) => typeof v === 'string' && v.trim() !== ''
|
|
41
|
+
|
|
42
|
+
function versionString(v) {
|
|
43
|
+
if (nonEmpty(v)) return v
|
|
44
|
+
if (isObject(v)) {
|
|
45
|
+
return nonEmpty(v.tag) ? v.tag : (nonEmpty(v.next) ? v.next : null)
|
|
46
|
+
}
|
|
47
|
+
return null
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function resolveShippedSha(m) {
|
|
51
|
+
const rel = isObject(m.release) ? m.release : {}
|
|
52
|
+
return rel.tagSha || rel.candidateSha || (rel.candidateIdentity && rel.candidateIdentity.sourceSha) || m.shippedSha || null
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// A release is over when it reached one of these. `discard` and `rollback` are terminal and
|
|
56
|
+
// SUCCESSFUL outcomes of the machine — the candidate was caught before or after exposure and
|
|
57
|
+
// the lane did its job — so a release that ends at either is complete, not failed.
|
|
58
|
+
const TERMINAL_STEPS = new Set(RELEASE_TERMINAL_STEPS)
|
|
59
|
+
|
|
60
|
+
// The keys the release schema defines (run-state.md § Release variant), plus the general
|
|
61
|
+
// run-level fields every manifest carries. Anything else is state written where nothing
|
|
62
|
+
// reads it. Deliberately generous: the point is to catch `z4Fix`, not to police a field
|
|
63
|
+
// somebody added for a good reason and documented.
|
|
64
|
+
const KNOWN_KEYS = new Set(CANONICAL_RELEASE_MANIFEST_FIELDS)
|
|
65
|
+
|
|
66
|
+
const hrs = (a, b) => {
|
|
67
|
+
const x = Date.parse(a); const y = Date.parse(b)
|
|
68
|
+
return Number.isFinite(x) && Number.isFinite(y) ? (y - x) / 3600000 : null
|
|
69
|
+
}
|
|
70
|
+
const fmtH = (h) => (h == null ? '—' : h < 1 ? `${Math.round(h * 60)}m` : `${h.toFixed(1)}h`)
|
|
71
|
+
|
|
72
|
+
export function releaseTimeline(manifest = {}) {
|
|
73
|
+
const errors = validateReleaseHistory(manifest)
|
|
74
|
+
if (errors.length) {
|
|
75
|
+
return { status: 'malformed', errors, events: [], intervals: [], metrics: null, truncated: null }
|
|
76
|
+
}
|
|
77
|
+
const history = isObject(manifest?.releaseHistory) ? manifest.releaseHistory : { events: [] }
|
|
78
|
+
const events = Array.isArray(history.events) ? structuredClone(history.events) : []
|
|
79
|
+
const intents = new Map((history.truncated?.openIntents || []).map((intent) => [
|
|
80
|
+
`${intent.subject}:${intent.correlationId}`, intent,
|
|
81
|
+
]))
|
|
82
|
+
const intervals = []
|
|
83
|
+
for (const event of events) {
|
|
84
|
+
if (event.kind === 'intent') intents.set(`${event.subject}:${event.correlationId}`, event)
|
|
85
|
+
if (event.kind !== 'result') continue
|
|
86
|
+
const key = `${event.subject}:${event.correlationId}`
|
|
87
|
+
const intent = intents.get(key)
|
|
88
|
+
if (!intent) continue
|
|
89
|
+
intervals.push({
|
|
90
|
+
correlationId: event.correlationId,
|
|
91
|
+
subject: event.subject,
|
|
92
|
+
status: event.outcome,
|
|
93
|
+
startedAt: intent.at,
|
|
94
|
+
endedAt: event.at,
|
|
95
|
+
durationMs: Date.parse(event.at) - Date.parse(intent.at),
|
|
96
|
+
})
|
|
97
|
+
intents.delete(key)
|
|
98
|
+
}
|
|
99
|
+
for (const intent of intents.values()) {
|
|
100
|
+
intervals.push({
|
|
101
|
+
correlationId: intent.correlationId,
|
|
102
|
+
subject: intent.subject,
|
|
103
|
+
status: 'waiting',
|
|
104
|
+
startedAt: intent.at,
|
|
105
|
+
endedAt: null,
|
|
106
|
+
durationMs: null,
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
intervals.sort((left, right) => Date.parse(left.startedAt) - Date.parse(right.startedAt))
|
|
110
|
+
return {
|
|
111
|
+
status: history.truncated ? 'truncated' : 'complete',
|
|
112
|
+
events,
|
|
113
|
+
intervals,
|
|
114
|
+
metrics: {
|
|
115
|
+
eventCount: events.length + (history.truncated?.count || 0),
|
|
116
|
+
completedWaitMs: (history.truncated?.completedWaitMs || 0) + intervals.reduce((total, interval) => total + (interval.durationMs || 0), 0),
|
|
117
|
+
failedWaitMs: (history.truncated?.failedWaitMs || 0) + intervals
|
|
118
|
+
.filter((interval) => interval.status === 'failed')
|
|
119
|
+
.reduce((total, interval) => total + (interval.durationMs || 0), 0),
|
|
120
|
+
unresolvedWaits: intervals.filter((interval) => interval.status === 'waiting').length,
|
|
121
|
+
},
|
|
122
|
+
truncated: history.truncated ? structuredClone(history.truncated) : null,
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function formatDuration(durationMs) {
|
|
127
|
+
if (durationMs == null) return 'waiting'
|
|
128
|
+
const minutes = Math.round(durationMs / 60000)
|
|
129
|
+
return minutes < 60 ? `${minutes}m` : `${Math.floor(minutes / 60)}h${String(minutes % 60).padStart(2, '0')}m`
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function renderReleaseTimeline(manifest) {
|
|
133
|
+
const timeline = releaseTimeline(manifest)
|
|
134
|
+
if (timeline.status === 'malformed') {
|
|
135
|
+
return `RELEASE TIMELINE: MALFORMED\n ${timeline.errors.join('\n ')}\n`
|
|
136
|
+
}
|
|
137
|
+
const rows = ['RELEASE TIMELINE']
|
|
138
|
+
if (timeline.truncated) {
|
|
139
|
+
rows.push(` truncated: ${timeline.truncated.count} event(s), release-event-${timeline.truncated.firstSequence} through release-event-${timeline.truncated.throughSequence}; boundary ${timeline.truncated.boundary.step ?? 'null'} / ${timeline.truncated.boundary.attemptState ?? 'null'}`)
|
|
140
|
+
}
|
|
141
|
+
if (!timeline.events.length) rows.push(' No machine-generated release events recorded.')
|
|
142
|
+
for (const event of timeline.events) {
|
|
143
|
+
if (event.kind === 'state') {
|
|
144
|
+
rows.push(` ${event.id} ${event.at} state: ${event.prior.step ?? 'null'} -> ${event.next.step ?? 'null'}; ${event.prior.attemptState ?? 'null'} -> ${event.next.attemptState ?? 'null'}`)
|
|
145
|
+
} else {
|
|
146
|
+
rows.push(` ${event.id} ${event.at} ${event.kind}: ${event.subject} ${event.correlationId}${event.outcome ? ` ${event.outcome}` : ''}`)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (timeline.intervals.length) rows.push(' intervals:')
|
|
150
|
+
for (const interval of timeline.intervals) {
|
|
151
|
+
rows.push(` ${interval.subject} ${interval.correlationId}: ${interval.status} (${formatDuration(interval.durationMs)})`)
|
|
152
|
+
}
|
|
153
|
+
return `${rows.join('\n')}\n`
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ---- the finders ----
|
|
157
|
+
|
|
158
|
+
function findStepOffEnum(m) {
|
|
159
|
+
const step = m.step
|
|
160
|
+
if (!nonEmpty(step) || RELEASE_STEPS.includes(step)) return null
|
|
161
|
+
return {
|
|
162
|
+
id: 'step-off-enum',
|
|
163
|
+
severity: 'high',
|
|
164
|
+
costMinutes: null,
|
|
165
|
+
headline: `step is \`${step}\`, which is not a release step`,
|
|
166
|
+
detail: `\`step\` is the resume key — the one field a dead session re-enters at — and it is an enum: ${RELEASE_STEPS.join(' | ')}. A freeform value cannot be routed on, so a resumed session cannot tell whether this release shipped, is mid-deploy, or needs a rollback.`,
|
|
167
|
+
evidence: [
|
|
168
|
+
`recorded: ${JSON.stringify(step)}`,
|
|
169
|
+
'`run-state.mjs validate` REFUSES this value — so validate was never run on this release',
|
|
170
|
+
],
|
|
171
|
+
recommendation: 'Record the enum step and put the detail elsewhere (`terminalState`, `note`). Then run `run-state.mjs validate <slug>` at the handoff — it already catches this, so every occurrence is a release where validate was not run.',
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function findStoppedMidMachine(m) {
|
|
176
|
+
const step = m.step
|
|
177
|
+
// An off-enum step is already the louder finding, and terminality is undecidable there —
|
|
178
|
+
// saying so twice in different words reads as two problems.
|
|
179
|
+
if (!nonEmpty(step) || !RELEASE_STEPS.includes(step) || TERMINAL_STEPS.has(step)) return null
|
|
180
|
+
const age = hrs(m.updatedAt, new Date().toISOString())
|
|
181
|
+
return {
|
|
182
|
+
id: 'stopped-mid-machine',
|
|
183
|
+
severity: 'high',
|
|
184
|
+
costMinutes: null,
|
|
185
|
+
headline: `the release stopped at \`${step}\` and never recorded a terminal step`,
|
|
186
|
+
detail: 'A release that stops mid-machine leaves production in a state only the tree can answer for. At `validate` a candidate may be serving nobody and costing money; at `expose` a traffic shift may be half-applied. Neither is visible from state, and the manifest is what a later session reads first.',
|
|
187
|
+
evidence: [
|
|
188
|
+
`last write: ${m.updatedAt ?? '—'}${age != null && age > 24 ? ` (${Math.round(age / 24)} days ago)` : ''}`,
|
|
189
|
+
`terminal steps are: ${[...TERMINAL_STEPS].join(', ')}`,
|
|
190
|
+
...(isObject(m.release) && nonEmpty(m.release.candidateRevision)
|
|
191
|
+
? [`a candidate revision is recorded and unresolved: ${m.release.candidateRevision} — check whether it still exists at 0% traffic`] : []),
|
|
192
|
+
],
|
|
193
|
+
recommendation: 'Finish the machine or record the outcome that actually happened — `done`, `discard` (the candidate was deleted pre-exposure), or `rollback`. If the release was abandoned, `discard` with a note is the honest record; silence is not.',
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function findNoVerification(m) {
|
|
198
|
+
if (isObject(m.verification) || !nonEmpty(m.step)) return null
|
|
199
|
+
// Only owed once the machine has got far enough to have verified something. A release
|
|
200
|
+
// that stopped at intake owes no verification record and faulting it is noise.
|
|
201
|
+
const reached = ['verify', 'expose', 'done'].includes(m.step) || m.step === 'validate'
|
|
202
|
+
if (!reached) return null
|
|
203
|
+
return {
|
|
204
|
+
id: 'no-verification-record',
|
|
205
|
+
severity: 'medium',
|
|
206
|
+
costMinutes: null,
|
|
207
|
+
headline: 'no `verification` record, on a release that reached ' + `\`${m.step}\``,
|
|
208
|
+
detail: 'The verification block is the evidence that the thing which shipped was checked — the candidate\'s ALIVE verdict, the re-check fence readings, the serving confirmation. Without it the handoff is asserting a verified release from memory, which is exactly the claim the record exists to make checkable.',
|
|
209
|
+
evidence: [`step: ${m.step}`, 'verification: absent'],
|
|
210
|
+
recommendation: 'Record the verification as it happens rather than at the handoff. Across the corpus this is the lane\'s most-skipped record — see references/postmortem.md for the count.',
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function findAdHocKeys(m) {
|
|
215
|
+
const extra = Object.keys(m).filter((k) => !KNOWN_KEYS.has(k))
|
|
216
|
+
if (!extra.length) return null
|
|
217
|
+
return {
|
|
218
|
+
id: 'adhoc-manifest-keys',
|
|
219
|
+
severity: extra.length >= 5 ? 'medium' : 'low',
|
|
220
|
+
costMinutes: null,
|
|
221
|
+
headline: `${extra.length} manifest key(s) outside the release schema`,
|
|
222
|
+
detail: 'State written to a key nothing reads is state that did not survive: no gate checks it, no resume routes on it, and `report.mjs` will not render it. It looks like a record and behaves like a comment.',
|
|
223
|
+
evidence: [extra.slice(0, 12).join(', ') + (extra.length > 12 ? `, … (+${extra.length - 12})` : '')],
|
|
224
|
+
recommendation: 'Put it in a schema field, or in `note`/`terminalState` where a reader will find it. Roughly half of all releases wrote at least one such key — see references/postmortem.md.',
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function findLongRelease(m) {
|
|
229
|
+
const h = hrs(m.createdAt, m.updatedAt)
|
|
230
|
+
// Well past "a queue was slow" — an order of magnitude over the measured median
|
|
231
|
+
// (references/postmortem.md). Kept as a bare threshold so the median can be re-measured
|
|
232
|
+
// there without this constant silently disagreeing with it.
|
|
233
|
+
if (h == null || h < 8) return null
|
|
234
|
+
return {
|
|
235
|
+
id: 'long-release',
|
|
236
|
+
severity: 'low',
|
|
237
|
+
costMinutes: Math.round(h * 60),
|
|
238
|
+
headline: `the release ran ${fmtH(h)} — an order of magnitude over the usual`,
|
|
239
|
+
detail: 'Releases are normally fast — the lane is mostly waiting on watchers. A long one is usually a release paused for a human and resumed later, which is fine, or one stalled on a gate nobody was watching, which is not. The manifest cannot tell those apart, so this is a prompt to check rather than a defect.',
|
|
240
|
+
evidence: [`createdAt ${m.createdAt ?? '—'}`, `updatedAt ${m.updatedAt ?? '—'}`],
|
|
241
|
+
recommendation: 'If it was waiting on a human, that is the answer and no change is owed. If it stalled on a watcher, that is a continuation-trigger miss (SKILL.md: a watcher firing is a continuation, not a checkpoint).',
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function findMetadataPrIncomplete(m) {
|
|
246
|
+
const rel = isObject(m.release) ? m.release : {}
|
|
247
|
+
const attempt = rel.attempt || {}
|
|
248
|
+
// Only verified-sha releases that actually reached `done` owe a metadata PR. Rollbacks
|
|
249
|
+
// and discards do not; a release that stopped mid-machine already has that finding.
|
|
250
|
+
if (m.step !== 'done' || attempt.state !== 'released') return null
|
|
251
|
+
const status = metadataPrStatus(rel)
|
|
252
|
+
if (!status || status.complete) return null
|
|
253
|
+
return {
|
|
254
|
+
id: 'metadata-pr-incomplete',
|
|
255
|
+
severity: 'high',
|
|
256
|
+
costMinutes: null,
|
|
257
|
+
headline: 'released attempt has no valid metadata PR',
|
|
258
|
+
detail: 'The verified-sha-github-flow contract requires `metadata-sync.mjs open` or `metadata-sync.mjs na` to record `release.metadataPr` after the final claim. A released attempt without a valid record is incomplete; report.mjs flags it owed, and the handoff must not treat it as done.',
|
|
259
|
+
evidence: [
|
|
260
|
+
`step: ${m.step}`,
|
|
261
|
+
`attempt.state: ${attempt.state}`,
|
|
262
|
+
`release.metadataPr: ${JSON.stringify(rel.metadataPr)}`,
|
|
263
|
+
...(isObject(rel.metadataSync)
|
|
264
|
+
? [`legacy metadataSync present: ${JSON.stringify(rel.metadataSync)}`] : []),
|
|
265
|
+
],
|
|
266
|
+
recommendation: 'Run `metadata-sync.mjs open` if a CHANGELOG/package version PR is owed, or `metadata-sync.mjs na --reason <text>` if not applicable. If a legacy `metadataSync` record exists, run `metadata-sync.mjs migrate`.',
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const RELEASE_FINDERS = [
|
|
271
|
+
findStepOffEnum,
|
|
272
|
+
findStoppedMidMachine,
|
|
273
|
+
findNoVerification,
|
|
274
|
+
findAdHocKeys,
|
|
275
|
+
findLongRelease,
|
|
276
|
+
findMetadataPrIncomplete,
|
|
277
|
+
]
|
|
278
|
+
|
|
279
|
+
// The version the attempts of this release were cut for — what the version-level post-mortem
|
|
280
|
+
// (#961, version-postmortem.mjs) discovers durable bundles by. Same resolution the summary uses.
|
|
281
|
+
export function releaseVersion(m) {
|
|
282
|
+
const rel = isObject(m?.release) ? m.release : {}
|
|
283
|
+
return versionString(rel.version) ?? versionString(isObject(m?.envelope) ? m.envelope.version : null)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// The rc circuit breaker (#962), reported as a fact — like a rollback, a hold that happened
|
|
287
|
+
// and was recorded is the machine WORKING, so this is never a faulting finding: what the
|
|
288
|
+
// post-mortem owes is whether the breaker fired and how it was resolved (the issue's AC).
|
|
289
|
+
// The record lives at `release.circuitBreaker` — the decision JSON rc-circuit-breaker.mjs
|
|
290
|
+
// printed and the lane merged onto the manifest before the rc mint.
|
|
291
|
+
export function circuitBreakerStatus(m) {
|
|
292
|
+
const rel = isObject(m.release) ? m.release : {}
|
|
293
|
+
const cb = isObject(rel.circuitBreaker) ? rel.circuitBreaker : null
|
|
294
|
+
if (!cb || !nonEmpty(cb.decision)) return null
|
|
295
|
+
if (cb.decision === 'proceed') {
|
|
296
|
+
return { fired: false, resolution: null, line: 'rc circuit breaker: did not fire (evaluated below threshold)' }
|
|
297
|
+
}
|
|
298
|
+
const count = Number.isInteger(cb.qualifyingCount) ? cb.qualifyingCount : '?'
|
|
299
|
+
if (cb.decision === 'authorized-continue' && isObject(cb.authorization) && nonEmpty(cb.authorization.authorizedBy)) {
|
|
300
|
+
return {
|
|
301
|
+
fired: true,
|
|
302
|
+
resolution: `authorized-continue by ${cb.authorization.authorizedBy}`,
|
|
303
|
+
line: `rc circuit breaker fired — authorized-continue by ${cb.authorization.authorizedBy} (${count} qualifying failure(s))`,
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
fired: true,
|
|
308
|
+
resolution: 'unresolved at this record',
|
|
309
|
+
line: `rc circuit breaker FIRED (${count} qualifying) — unresolved`,
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function releaseSummary(m) {
|
|
314
|
+
const rel = isObject(m.release) ? m.release : {}
|
|
315
|
+
const version = releaseVersion(m)
|
|
316
|
+
const shippedSha = resolveShippedSha(m)
|
|
317
|
+
const metrics = {
|
|
318
|
+
releaseState: classifyReleaseManifest(m),
|
|
319
|
+
step: m.step ?? null,
|
|
320
|
+
version: version ?? null,
|
|
321
|
+
shippedSha: nonEmpty(shippedSha) ? shippedSha.slice(0, 7) : null,
|
|
322
|
+
runHours: (() => { const h = hrs(m.createdAt, m.updatedAt); return h == null ? null : Number(h.toFixed(2)) })(),
|
|
323
|
+
rolledBack: Boolean(m.rollback),
|
|
324
|
+
burned: Boolean(rel.burned),
|
|
325
|
+
// #962 — present only when the lane recorded a breaker decision: an absent record and a
|
|
326
|
+
// breaker that did not fire are different statements, and a null here would read as a
|
|
327
|
+
// measurement (the same trap the inFlightCap column guard names).
|
|
328
|
+
...(circuitBreakerStatus(m)
|
|
329
|
+
? { circuitBreaker: { fired: circuitBreakerStatus(m).fired, resolution: circuitBreakerStatus(m).resolution } }
|
|
330
|
+
: {}),
|
|
331
|
+
}
|
|
332
|
+
const cbLine = circuitBreakerStatus(m)?.line
|
|
333
|
+
const bits = [
|
|
334
|
+
`step ${metrics.step ?? '—'}`,
|
|
335
|
+
version ? `version ${version}` : 'unversioned (dev/staging)',
|
|
336
|
+
`${fmtH(metrics.runHours)} wall-clock`,
|
|
337
|
+
...(metrics.rolledBack ? ['ROLLED BACK'] : []),
|
|
338
|
+
...(metrics.burned ? ['version burned'] : []),
|
|
339
|
+
...(cbLine ? [cbLine] : []),
|
|
340
|
+
]
|
|
341
|
+
return {
|
|
342
|
+
kind: 'release',
|
|
343
|
+
metrics,
|
|
344
|
+
summaryLine: bits.join(' · '),
|
|
345
|
+
blindSpots: 'what the tree and the live service actually hold — a candidate revision this pass reports as recorded may already be gone, and one it cannot see may still be serving',
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export function releaseProfile(manifest = {}) {
|
|
350
|
+
return {
|
|
351
|
+
...profile(manifest, { finders: RELEASE_FINDERS, summary: releaseSummary }),
|
|
352
|
+
timeline: releaseTimeline(manifest),
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export function renderReleasePostmortem(manifest = {}) {
|
|
357
|
+
return `${renderProfile(releaseProfile(manifest))}\n${renderReleaseTimeline(manifest)}`
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export function renderReleasePostmortemIssue(manifest = {}) {
|
|
361
|
+
const issue = renderProfileIssue(releaseProfile(manifest), 'resolve-release')
|
|
362
|
+
return {
|
|
363
|
+
...issue,
|
|
364
|
+
body: `${issue.body}\n\n## Release timeline\n\n\`\`\`text\n${renderReleaseTimeline(manifest)}\`\`\``,
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export function saveReleasePostmortem(manifest = {}, env = process.env, now = new Date()) {
|
|
369
|
+
return saveProfile(releaseProfile(manifest), env, now)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// A release is profiled once it reaches a terminal step. Unlike the delivery lane — where an
|
|
373
|
+
// unfinished run is simply in flight — a release that never reaches one is itself a finding
|
|
374
|
+
// (`stopped-mid-machine`), so this is deliberately NOT the gate on whether the pass has
|
|
375
|
+
// anything to say. It is only the gate on the AUTOMATIC save, and the standalone command
|
|
376
|
+
// profiles a stalled release on demand, which is how that finding gets seen at all.
|
|
377
|
+
export function releaseIsTerminal(manifest = {}) {
|
|
378
|
+
return TERMINAL_STEPS.has(manifest?.step)
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
export { RELEASE_FINDERS, TERMINAL_STEPS, KNOWN_KEYS }
|