@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,554 @@
|
|
|
1
|
+
// scope-class — infer a unit's SCOPE CLASS from its net `merge-base...HEAD` diff.
|
|
2
|
+
//
|
|
3
|
+
// The axis this adds, and why it is not the risk tier. `highRisk` decides HOW DEEP
|
|
4
|
+
// the review goes. `scopeClass` decides WHICH COVERAGE/EVIDENCE ARTIFACTS APPLY.
|
|
5
|
+
// They are orthogonal on purpose: `.mergify.yml`, CI workflows, Dockerfile base
|
|
6
|
+
// images, IAM bindings and feature-flag defaults are all config-only *and* commonly
|
|
7
|
+
// high-risk. A rule of the form "config-only ⇒ lighter review" fires hardest exactly
|
|
8
|
+
// where it is most wrong, so this file never touches review depth — see
|
|
9
|
+
// SCOPE_KEPT_OBLIGATIONS, which is identical for every class and is asserted so.
|
|
10
|
+
//
|
|
11
|
+
// Named incident (the removal path's rule 1 — a new artifact names the incident it
|
|
12
|
+
// would have caught): a consumer product repo, PR #1065, a policy-only diff
|
|
13
|
+
// (`.mergify.yml` −5, `mergify-policy.test.ts` +2/−5) whose reviewer wrote:
|
|
14
|
+
// "The generic coverage checklist was generated for the policy-only diff but is
|
|
15
|
+
// not fully applicable without a dedicated checklist artifact."
|
|
16
|
+
// Every other artifact in that run was load-bearing (`mergify config validate`,
|
|
17
|
+
// `config simulate` against a live PR, the focused policy suite, `scan-diff` = 0).
|
|
18
|
+
// The checklist was the only one that cost work and said nothing.
|
|
19
|
+
//
|
|
20
|
+
// DENY-BY-DEFAULT is the whole safety argument. A unit is `no-surface` only if EVERY
|
|
21
|
+
// path in the net diff matches a configured non-runtime pattern; one unmatched path
|
|
22
|
+
// ⇒ `surface-bearing`. The asymmetry: misclassifying config as surface-bearing costs
|
|
23
|
+
// one useless checklist, misclassifying source as `no-surface` silently drops the
|
|
24
|
+
// breadth and depth gates. So every ambiguous case fails toward `surface-bearing` —
|
|
25
|
+
// an empty diff, a malformed config, a non-array input.
|
|
26
|
+
//
|
|
27
|
+
// THE COROLLARY DENY-BY-DEFAULT DEPENDS ON (PR #519 round 2, hazard
|
|
28
|
+
// `rename-preimage-escapes-path-classifiers`): **no changed path may reach the
|
|
29
|
+
// classifier in a form that hides what it is. Every side of every change is a changed
|
|
30
|
+
// path, and anything the parser cannot take at face value fails toward
|
|
31
|
+
// `surface-bearing`.** Deny-by-default is only as good as the path list it is handed —
|
|
32
|
+
// a path the list never contains cannot be denied. The reported instance was a rename:
|
|
33
|
+
// `git mv src/lib/auth.ts docs/auth-notes.md` classified `no-surface`, because only the
|
|
34
|
+
// `b/` side survived, so a diff that DELETED a runtime source file looked like a docs
|
|
35
|
+
// edit. Members closed here, all four: the rename pre-image (`rename from`), copies
|
|
36
|
+
// (`copy from`, same shape), the `--diff` mode's `git diff --name-only` (which collapses
|
|
37
|
+
// a detected rename to its post-image one layer above pathsFromDiff), and paths the
|
|
38
|
+
// parser cannot take at face value — a `..` segment (`docs/../src/app.ts` reads as
|
|
39
|
+
// `docs/**` to a glob and as `src/app.ts` to a filesystem) and an unparseable
|
|
40
|
+
// `diff --git` header (a changed path of UNKNOWN identity is not a path that matched
|
|
41
|
+
// nothing). See isOpaquePath and pathsFromDiff.
|
|
42
|
+
//
|
|
43
|
+
// THE ORACLE IS A REQUIREMENT, NOT A WAIVER. The pattern table carries the oracle
|
|
44
|
+
// beside the pattern because both are repo-specific and they answer one question:
|
|
45
|
+
// "this artifact is inapplicable — so what proves the change instead?" A matched
|
|
46
|
+
// class with no declared oracle is not a pass, it is the finding (`oracle-undeclared`,
|
|
47
|
+
// blocking): write one, or declare the class unproven-by-design (`oracle: null` +
|
|
48
|
+
// `unprovenReason`), which forces the Review Contract to say so.
|
|
49
|
+
//
|
|
50
|
+
// node scope-class.mjs classify --diff <base> # git diff --name-only <base>...HEAD
|
|
51
|
+
// node scope-class.mjs classify --stdin # newline-separated paths OR a unified diff
|
|
52
|
+
// node scope-class.mjs classify --paths <file> # same, from a file
|
|
53
|
+
// [--json] [--config <file>] [--root <dir>]
|
|
54
|
+
// node scope-class.mjs table [--json] # print the resolved pattern→oracle table
|
|
55
|
+
//
|
|
56
|
+
// Exit codes: 0 = classified (either class), 1 = a blocking finding, 2 = usage error.
|
|
57
|
+
// `surface-bearing` is exit 0 — it is a normal, safe outcome, not a failure.
|
|
58
|
+
//
|
|
59
|
+
// Doctrine: references/process/scope-class.md.
|
|
60
|
+
|
|
61
|
+
import fs from 'node:fs'
|
|
62
|
+
import path from 'node:path'
|
|
63
|
+
import { execFileSync } from 'node:child_process'
|
|
64
|
+
import { fileURLToPath } from 'node:url'
|
|
65
|
+
|
|
66
|
+
export const SURFACE_BEARING = 'surface-bearing'
|
|
67
|
+
export const NO_SURFACE = 'no-surface'
|
|
68
|
+
/** The enum `units[].scopeClass` is bounded by (run-state.mjs imports this). */
|
|
69
|
+
export const SCOPE_CLASSES = [SURFACE_BEARING, NO_SURFACE]
|
|
70
|
+
|
|
71
|
+
// ---- what `no-surface` NEVER drops -----------------------------------------
|
|
72
|
+
//
|
|
73
|
+
// Rendered into every result, identical for both classes, and asserted identical by
|
|
74
|
+
// the tests. This is the mechanized form of "an inferred scope class never lightens
|
|
75
|
+
// the review": if someone later tries to route a review obligation through this
|
|
76
|
+
// classifier, the constant list is where it has to be added, in the open.
|
|
77
|
+
export const SCOPE_KEPT_OBLIGATIONS = Object.freeze([
|
|
78
|
+
"scan-diff's findings channel — zero-tolerance for EVERY scope class",
|
|
79
|
+
'CI green on the exact head',
|
|
80
|
+
'the independent review on a different model — same reviewer spawn, same model-diversity rule, same verdict bar',
|
|
81
|
+
'delivery recording with ancestry proof',
|
|
82
|
+
])
|
|
83
|
+
|
|
84
|
+
// ---- the built-in default table (patterns → oracle) -------------------------
|
|
85
|
+
//
|
|
86
|
+
// Repo-tunable via `coverage.config.json` → `scopeClass` (see resolveScopeClassConfig).
|
|
87
|
+
// `highRisk: true` marks the paths that govern merge authority, CI, deploy and IAM —
|
|
88
|
+
// these set the risk auto-flag ALONGSIDE `no-surface`, never instead of it.
|
|
89
|
+
export const DEFAULT_SCOPE_CLASSES = Object.freeze([
|
|
90
|
+
{
|
|
91
|
+
id: 'merge-policy',
|
|
92
|
+
patterns: ['.mergify.yml', '.mergify.yaml', '.github/mergify.yml', '.github/CODEOWNERS', 'CODEOWNERS', '.github/branch-protection*.y*ml'],
|
|
93
|
+
oracle: '`mergify config validate` + `mergify config simulate` against a live PR',
|
|
94
|
+
highRisk: true,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
id: 'ci-workflows',
|
|
98
|
+
patterns: ['.github/workflows/**', '.github/actions/**', '.gitlab-ci.yml', 'azure-pipelines.yml'],
|
|
99
|
+
oracle: '`actionlint`',
|
|
100
|
+
highRisk: true,
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: 'deploy-config',
|
|
104
|
+
patterns: ['cloudbuild*.y*ml', 'skaffold*.y*ml', 'clouddeploy*.y*ml', 'deploy/**', 'k8s/**', 'kustomize/**', 'Dockerfile', '**/Dockerfile', '**/*.dockerfile', 'docker-compose*.y*ml'],
|
|
105
|
+
oracle: 'render/build the artifact without deploying — e.g. `skaffold render`, `kustomize build`, `docker build --check`',
|
|
106
|
+
highRisk: true,
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 'iam-policy',
|
|
110
|
+
patterns: ['iam/**', '**/*.iam.y*ml', '**/*.iam.json', 'policies/**', '**/*.rego'],
|
|
111
|
+
oracle: 'policy evaluation against the intended principals — e.g. `opa test`, `gcloud policy-troubleshoot`',
|
|
112
|
+
highRisk: true,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: 'docs',
|
|
116
|
+
patterns: ['docs/**', '**/*.md', '**/*.mdx', 'LICENSE', 'CODE_OF_CONDUCT*', 'CONTRIBUTING*'],
|
|
117
|
+
// Declared unproven BY DESIGN: prose has no executable oracle. Declaring it is
|
|
118
|
+
// the point — the reviewer learns the change is unproven rather than assuming a
|
|
119
|
+
// gate covered it. This is a declaration, not a waiver: it still has to be said
|
|
120
|
+
// in the Review Contract (inapplicableArtifacts carries it there).
|
|
121
|
+
oracle: null,
|
|
122
|
+
unprovenReason: 'documentation prose has no executable oracle — unproven by design; say so in the Review Contract rather than implying a gate covered it',
|
|
123
|
+
highRisk: false,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
id: 'lockfiles',
|
|
127
|
+
patterns: ['**/package-lock.json', '**/pnpm-lock.yaml', '**/yarn.lock', '**/uv.lock', '**/poetry.lock', '**/Cargo.lock', '**/go.sum', '**/Gemfile.lock'],
|
|
128
|
+
oracle: 'install determinism — re-run the repo installer (`npm ci` / `uv sync --frozen` / …) then `git diff --exit-code <lockfile>`',
|
|
129
|
+
highRisk: false,
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: 'generated',
|
|
133
|
+
patterns: ['**/generated/**', '**/__generated__/**', '**/*.generated.*', '**/*.gen.*', '**/*.snap'],
|
|
134
|
+
oracle: 'regen determinism — re-run the generator then `git diff --exit-code`',
|
|
135
|
+
highRisk: false,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
id: 'tests',
|
|
139
|
+
// Test files do not break the classification (#1065 touched `mergify-policy.test.ts`
|
|
140
|
+
// and must still classify `no-surface`). The guard against "weakened the test so the
|
|
141
|
+
// config passes" is NOT this table — it is scan-diff's findings channel, which stays
|
|
142
|
+
// zero-tolerance for every class (SCOPE_KEPT_OBLIGATIONS).
|
|
143
|
+
patterns: ['**/*.test.*', '**/*.spec.*', 'tests/**', 'test/**', '**/__tests__/**', 'e2e/**', '**/*.coverage.yml'],
|
|
144
|
+
oracle: 'run the changed test suite and paste its output',
|
|
145
|
+
highRisk: false,
|
|
146
|
+
},
|
|
147
|
+
])
|
|
148
|
+
|
|
149
|
+
export const DEFAULT_SCOPE_CLASS_CONFIG = Object.freeze({ classes: DEFAULT_SCOPE_CLASSES })
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Merge a repo's `scopeClass` override over the defaults.
|
|
153
|
+
* - `classes` REPLACES the table wholesale (a repo that wants full control gets it).
|
|
154
|
+
* - `extraClasses` is additive and checked BEFORE the defaults, so a repo's own
|
|
155
|
+
* declaration wins over an overlapping built-in guess — the built-in any-depth
|
|
156
|
+
* `.rego` pattern must not decide the oracle for a repo that declared its own
|
|
157
|
+
* `policy/` class.
|
|
158
|
+
* Anything malformed falls back to the defaults — a broken config must never widen
|
|
159
|
+
* `no-surface` (it would fail in the expensive direction).
|
|
160
|
+
*/
|
|
161
|
+
export function resolveScopeClassConfig(override = {}) {
|
|
162
|
+
const o = override && typeof override === 'object' ? override : {}
|
|
163
|
+
const base = Array.isArray(o.classes) && o.classes.length ? o.classes : DEFAULT_SCOPE_CLASSES
|
|
164
|
+
const extra = Array.isArray(o.extraClasses) ? o.extraClasses : []
|
|
165
|
+
const classes = [...extra, ...base].filter((c) => c && typeof c.id === 'string' && Array.isArray(c.patterns) && c.patterns.length)
|
|
166
|
+
return { classes: classes.length ? classes : DEFAULT_SCOPE_CLASSES }
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function readConfigFile(p) {
|
|
170
|
+
if (!fs.existsSync(p)) return null
|
|
171
|
+
try {
|
|
172
|
+
return resolveScopeClassConfig(JSON.parse(fs.readFileSync(p, 'utf8')).scopeClass ?? {})
|
|
173
|
+
} catch (e) {
|
|
174
|
+
process.stderr.write(`scope-class: ignoring malformed ${p} (${e.message}); running on the built-in default table\n`)
|
|
175
|
+
return resolveScopeClassConfig({})
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Discover `coverage.config.json` / `.coverage.config.json` in rootDir. Never throws. */
|
|
180
|
+
export function loadScopeClassConfig(rootDir = process.cwd()) {
|
|
181
|
+
for (const name of ['coverage.config.json', '.coverage.config.json']) {
|
|
182
|
+
const got = readConfigFile(path.join(rootDir, name))
|
|
183
|
+
if (got) return got
|
|
184
|
+
}
|
|
185
|
+
return resolveScopeClassConfig({})
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Resolve an explicit `--config <file>`; warns (non-fatal) when it is missing. */
|
|
189
|
+
export function loadScopeClassConfigFromFile(configFile, rootDir = process.cwd()) {
|
|
190
|
+
if (!configFile) return loadScopeClassConfig(rootDir)
|
|
191
|
+
const got = readConfigFile(configFile)
|
|
192
|
+
if (got) return got
|
|
193
|
+
process.stderr.write(`scope-class: --config ${configFile} not found; running on the built-in default table\n`)
|
|
194
|
+
return resolveScopeClassConfig({})
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ---- globbing --------------------------------------------------------------
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Compile a glob to an anchored RegExp. `*` stops at `/`, `**` crosses it, `?` is one
|
|
201
|
+
* non-separator char. Deliberately tiny and dependency-free: this runs in a producer's
|
|
202
|
+
* close-out, and a classifier that needs an install is one that gets skipped.
|
|
203
|
+
*
|
|
204
|
+
* A leading double-star segment also matches the bare basename (so a glob of
|
|
205
|
+
* "double-star slash *.md" matches "c.md"), which is what every reader expects and
|
|
206
|
+
* what a naive translation gets wrong.
|
|
207
|
+
*/
|
|
208
|
+
export function globToRegExp(glob) {
|
|
209
|
+
let re = ''
|
|
210
|
+
const g = String(glob)
|
|
211
|
+
for (let i = 0; i < g.length; i++) {
|
|
212
|
+
const c = g[i]
|
|
213
|
+
if (c === '*') {
|
|
214
|
+
if (g[i + 1] === '*') {
|
|
215
|
+
// `**/` → any number of leading segments, including none.
|
|
216
|
+
if (g[i + 2] === '/') { re += '(?:[^/]+/)*'; i += 2 } else { re += '.*'; i += 1 }
|
|
217
|
+
} else {
|
|
218
|
+
re += '[^/]*'
|
|
219
|
+
}
|
|
220
|
+
} else if (c === '?') re += '[^/]'
|
|
221
|
+
else re += c.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
222
|
+
}
|
|
223
|
+
return new RegExp(`^${re}$`)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const patternCache = new Map()
|
|
227
|
+
function compiled(pattern) {
|
|
228
|
+
if (!patternCache.has(pattern)) patternCache.set(pattern, globToRegExp(pattern))
|
|
229
|
+
return patternCache.get(pattern)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** The first class whose patterns match, or null (⇒ the path is surface-bearing). */
|
|
233
|
+
export function matchScopeClass(filePath, config = DEFAULT_SCOPE_CLASS_CONFIG) {
|
|
234
|
+
const p = normalizePath(filePath)
|
|
235
|
+
if (!p) return null
|
|
236
|
+
// An opaque path is never matched — it lands in `unmatched` and forces
|
|
237
|
+
// surface-bearing, rather than being globbed on a spelling it does not mean.
|
|
238
|
+
if (isOpaquePath(p)) return null
|
|
239
|
+
for (const cls of config.classes || []) {
|
|
240
|
+
if ((cls.patterns || []).some((pat) => compiled(pat).test(p))) return cls
|
|
241
|
+
}
|
|
242
|
+
return null
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function normalizePath(p) {
|
|
246
|
+
if (typeof p !== 'string') return ''
|
|
247
|
+
return p.trim().replace(/^\.\//, '')
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Marker carried by pathsFromDiff for a `diff --git` header it could not split. */
|
|
251
|
+
export const UNPARSEABLE_PATH = '<unparseable diff header>'
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* A path the classifier must NOT take at face value — it fails toward `surface-bearing`
|
|
255
|
+
* by matching no class, and it is deliberately NOT dropped (a dropped path leaves an
|
|
256
|
+
* all-matched set behind, which is exactly the `no-surface` misclassification the whole
|
|
257
|
+
* design exists to prevent).
|
|
258
|
+
*
|
|
259
|
+
* - a `..` segment: `docs/../src/app.ts` matches `docs/**` as a string and means
|
|
260
|
+
* `src/app.ts` as a file, so any glob verdict on it is meaningless;
|
|
261
|
+
* - the unparseable-header sentinel: a changed path whose identity is unknown.
|
|
262
|
+
*/
|
|
263
|
+
export function isOpaquePath(p) {
|
|
264
|
+
const s = normalizePath(p)
|
|
265
|
+
if (!s) return false
|
|
266
|
+
if (s.startsWith(UNPARSEABLE_PATH)) return true
|
|
267
|
+
return s.split('/').includes('..')
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// ---- diff parsing ----------------------------------------------------------
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* BOTH SIDES of every entry in a unified diff. Not "post-image paths" — that was the
|
|
274
|
+
* bug: a rename's pre-image is a path the diff DELETES, and dropping it let
|
|
275
|
+
* `git mv src/lib/auth.ts docs/auth-notes.md` classify `no-surface`.
|
|
276
|
+
*
|
|
277
|
+
* Per entry: take `a/` and `b/` from the `diff --git` header, then let an explicit
|
|
278
|
+
* `rename from`/`rename to` (and `copy from`/`copy to`, identical shape) OVERRIDE
|
|
279
|
+
* them — those lines are the unambiguous record, and the header is not: git emits
|
|
280
|
+
* unquoted spaces in it (`diff --git a/a b.ts b/b c.ts`), so the split is a guess.
|
|
281
|
+
* Emit `b`, plus `a` whenever it differs. An add and a delete both have `a === b`
|
|
282
|
+
* and yield one path; a copy's source is unmodified but is emitted anyway, because
|
|
283
|
+
* deny-by-default prefers one useless checklist over a dropped gate.
|
|
284
|
+
*
|
|
285
|
+
* A header this cannot split yields the UNPARSEABLE_PATH sentinel rather than nothing:
|
|
286
|
+
* a changed path of unknown identity must reach `unmatched`, not vanish. Quoted paths
|
|
287
|
+
* (`"a/x y.ts"`) are unquoted.
|
|
288
|
+
*/
|
|
289
|
+
export function pathsFromDiff(text) {
|
|
290
|
+
const out = []
|
|
291
|
+
const push = (p) => { const n = normalizePath(p); if (n && !out.includes(n)) out.push(n) }
|
|
292
|
+
let pending = null
|
|
293
|
+
const flush = () => {
|
|
294
|
+
if (!pending) return
|
|
295
|
+
push(pending.b)
|
|
296
|
+
if (pending.a && pending.a !== pending.b) push(pending.a)
|
|
297
|
+
pending = null
|
|
298
|
+
}
|
|
299
|
+
for (const line of String(text || '').split(/\r?\n/)) {
|
|
300
|
+
if (/^diff --git /.test(line)) {
|
|
301
|
+
flush()
|
|
302
|
+
const m = /^diff --git (?:"?a\/(.+?)"?) (?:"?b\/(.+?)"?)$/.exec(line)
|
|
303
|
+
pending = m ? { a: m[1], b: m[2] } : { a: null, b: `${UNPARSEABLE_PATH} ${line}` }
|
|
304
|
+
continue
|
|
305
|
+
}
|
|
306
|
+
if (!pending) continue
|
|
307
|
+
const from = /^(?:rename|copy) from (?:"?)(.+?)(?:"?)$/.exec(line)
|
|
308
|
+
if (from) { pending.a = from[1]; continue }
|
|
309
|
+
const to = /^(?:rename|copy) to (?:"?)(.+?)(?:"?)$/.exec(line)
|
|
310
|
+
if (to) { pending.b = to[1]; continue }
|
|
311
|
+
}
|
|
312
|
+
flush()
|
|
313
|
+
return out
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/** True when the blob looks like a unified diff rather than a path list. */
|
|
317
|
+
export function looksLikeDiff(text) {
|
|
318
|
+
return /^diff --git /m.test(String(text || ''))
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// ---- classification --------------------------------------------------------
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Classify a unit's net diff. `paths` is the changed-path list (or use pathsFromDiff).
|
|
325
|
+
* Everything ambiguous fails toward `surface-bearing`.
|
|
326
|
+
*/
|
|
327
|
+
export function classifyScope(paths, config = DEFAULT_SCOPE_CLASS_CONFIG) {
|
|
328
|
+
const cfg = config && Array.isArray(config.classes) ? config : DEFAULT_SCOPE_CLASS_CONFIG
|
|
329
|
+
const kept = SCOPE_KEPT_OBLIGATIONS
|
|
330
|
+
|
|
331
|
+
if (!Array.isArray(paths) || paths.length === 0) {
|
|
332
|
+
return {
|
|
333
|
+
scopeClass: SURFACE_BEARING,
|
|
334
|
+
reason: Array.isArray(paths)
|
|
335
|
+
? 'no paths in the net diff — nothing to classify, so it fails toward surface-bearing (deny-by-default)'
|
|
336
|
+
: 'the changed-path input was not a list — it fails toward surface-bearing (deny-by-default)',
|
|
337
|
+
paths: [], unmatched: [], matched: [], oracles: [], unproven: [],
|
|
338
|
+
highRisk: false, highRiskRaiseOnly: true, findings: [], ok: true, kept,
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const classified = []
|
|
343
|
+
const unmatched = []
|
|
344
|
+
const byClass = new Map()
|
|
345
|
+
for (const raw of paths) {
|
|
346
|
+
const p = normalizePath(raw)
|
|
347
|
+
if (!p) continue
|
|
348
|
+
const cls = matchScopeClass(p, cfg)
|
|
349
|
+
classified.push({ path: p, class: cls ? cls.id : null })
|
|
350
|
+
if (!cls) { unmatched.push(p); continue }
|
|
351
|
+
if (!byClass.has(cls.id)) byClass.set(cls.id, { ...cls, paths: [] })
|
|
352
|
+
byClass.get(cls.id).paths.push(p)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (!classified.length) {
|
|
356
|
+
return {
|
|
357
|
+
scopeClass: SURFACE_BEARING,
|
|
358
|
+
reason: 'no usable paths in the net diff — it fails toward surface-bearing (deny-by-default)',
|
|
359
|
+
paths: [], unmatched: [], matched: [], oracles: [], unproven: [],
|
|
360
|
+
highRisk: false, highRiskRaiseOnly: true, findings: [], ok: true, kept,
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const matched = [...byClass.values()].map((m) => ({
|
|
365
|
+
id: m.id, paths: m.paths, oracle: m.oracle ?? null, unprovenReason: m.unprovenReason ?? null, highRisk: !!m.highRisk,
|
|
366
|
+
}))
|
|
367
|
+
const scopeClass = unmatched.length ? SURFACE_BEARING : NO_SURFACE
|
|
368
|
+
|
|
369
|
+
if (scopeClass === SURFACE_BEARING) {
|
|
370
|
+
return {
|
|
371
|
+
scopeClass,
|
|
372
|
+
reason: `${unmatched.length} path(s) match no configured non-runtime pattern — ${unmatched.slice(0, 5).join(', ')}${unmatched.length > 5 ? ', …' : ''}; one unmatched path is enough (deny-by-default)`,
|
|
373
|
+
paths: classified,
|
|
374
|
+
unmatched,
|
|
375
|
+
matched,
|
|
376
|
+
// The oracle requirement is scoped to the `no-surface` lane: a surface-bearing
|
|
377
|
+
// unit already owes the full breadth/depth gates, so raising an oracle finding
|
|
378
|
+
// there would be a second bill for the same obligation.
|
|
379
|
+
oracles: [], unproven: [], findings: [], ok: true,
|
|
380
|
+
highRisk: matched.some((m) => m.highRisk),
|
|
381
|
+
highRiskRaiseOnly: true,
|
|
382
|
+
kept,
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const oracles = []
|
|
387
|
+
const unproven = []
|
|
388
|
+
const findings = []
|
|
389
|
+
for (const m of matched) {
|
|
390
|
+
const hasOracle = typeof m.oracle === 'string' && m.oracle.trim().length > 0
|
|
391
|
+
const declaredUnproven = !hasOracle && typeof m.unprovenReason === 'string' && m.unprovenReason.trim().length > 0
|
|
392
|
+
if (hasOracle) oracles.push({ class: m.id, oracle: m.oracle })
|
|
393
|
+
else if (declaredUnproven) unproven.push({ class: m.id, reason: m.unprovenReason })
|
|
394
|
+
else {
|
|
395
|
+
findings.push({
|
|
396
|
+
code: 'oracle-undeclared',
|
|
397
|
+
severity: 'blocking',
|
|
398
|
+
class: m.id,
|
|
399
|
+
paths: m.paths,
|
|
400
|
+
message: `scope class "${m.id}" matched ${m.paths.length} path(s) but declares no oracle — the oracle REPLACES the checklist, it is not a waiver. Declare an oracle command for "${m.id}" in coverage.config.json → scopeClass, or declare it unproven-by-design (oracle: null + unprovenReason) and say so in the Review Contract.`,
|
|
401
|
+
})
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const names = matched.map((m) => m.id).sort()
|
|
406
|
+
return {
|
|
407
|
+
scopeClass,
|
|
408
|
+
reason: `every path in the net diff matches a configured non-runtime pattern (${names.join(', ')}) — no runtime surface changed`,
|
|
409
|
+
paths: classified,
|
|
410
|
+
unmatched: [],
|
|
411
|
+
matched,
|
|
412
|
+
oracles,
|
|
413
|
+
unproven,
|
|
414
|
+
findings,
|
|
415
|
+
ok: findings.length === 0,
|
|
416
|
+
// The risk auto-flag: merge/CI/deploy/IAM paths are config-only AND high-risk.
|
|
417
|
+
// RAISE-ONLY — a consumer ORs this into the unit's existing flag and NEVER writes
|
|
418
|
+
// `false` back over a set one (the orchestrator's manifest write enforces that).
|
|
419
|
+
highRisk: matched.some((m) => m.highRisk),
|
|
420
|
+
highRiskRaiseOnly: true,
|
|
421
|
+
kept,
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// ---- what the class derives downstream -------------------------------------
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* The smoke `not-applicable` REASON, derived from the scope class — never written
|
|
429
|
+
* per run. `no-surface` keeps the existing `gates.smoke = 'not-applicable'` +
|
|
430
|
+
* `smokeNotApplicableReason` path (a reasoned N/A reaches ALIVE, an unreasoned one
|
|
431
|
+
* stays DEAD); it is NOT a new skip path. Returns null for a surface-bearing unit,
|
|
432
|
+
* which still owes a real ALIVE.
|
|
433
|
+
*/
|
|
434
|
+
export function scopeSmokeReason(result) {
|
|
435
|
+
if (!result || result.scopeClass !== NO_SURFACE) return null
|
|
436
|
+
const names = (result.matched || []).map((m) => m.id).sort().join(', ')
|
|
437
|
+
return `scopeClass: no-surface — the net diff is entirely ${names} (no runtime surface to boot); proven instead by its declared oracle(s)`
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const INAPPLICABLE = [
|
|
441
|
+
['coverage-checklist', '`coverage-checklist.mjs generate` / `validate`', 'no surface rows to fill'],
|
|
442
|
+
['coverage-ledger', '`coverage-ledger.mjs validate`', 'nothing enters the surface inventory'],
|
|
443
|
+
['presentation-sweep', 'e2e route manifest + presentation sweep', 'no browser route changed'],
|
|
444
|
+
['test-criteria', 'TDD mode + the create-mode test-criteria gate', 'no behavioural surface to write criteria against — the declared oracle is the proof instead'],
|
|
445
|
+
]
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* The Review Contract rows a `no-surface` unit records `Not applicable` WITH a
|
|
449
|
+
* scope-derived reason — never generated-then-marked-N/A. Empty for a surface-bearing
|
|
450
|
+
* unit. Nothing on this list is a review-depth obligation, and the tests assert that:
|
|
451
|
+
* scan-diff, CI, the independent review and delivery are in SCOPE_KEPT_OBLIGATIONS.
|
|
452
|
+
*/
|
|
453
|
+
export function inapplicableArtifacts(result) {
|
|
454
|
+
if (!result || result.scopeClass !== NO_SURFACE) return []
|
|
455
|
+
const names = (result.matched || []).map((m) => m.id).sort().join(', ')
|
|
456
|
+
return INAPPLICABLE.map(([id, artifact, why]) => ({
|
|
457
|
+
id,
|
|
458
|
+
artifact,
|
|
459
|
+
reason: `Not applicable — scopeClass: no-surface (${names}): ${why}`,
|
|
460
|
+
}))
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// ---- CLI -------------------------------------------------------------------
|
|
464
|
+
|
|
465
|
+
function readPaths(flags) {
|
|
466
|
+
let raw = ''
|
|
467
|
+
if (flags.stdin) raw = fs.readFileSync(0, 'utf8')
|
|
468
|
+
else if (flags.paths) raw = fs.readFileSync(flags.paths, 'utf8')
|
|
469
|
+
else if (flags.diff) {
|
|
470
|
+
const base = execFileSync('git', ['merge-base', flags.diff, 'HEAD'], { encoding: 'utf8' }).trim()
|
|
471
|
+
// `--no-renames` is load-bearing, not tidiness: with rename detection on (git's
|
|
472
|
+
// default), `--name-only` collapses a rename to its post-image alone, so a source
|
|
473
|
+
// file moved out of a runtime tree is a deletion this classifier never sees — the
|
|
474
|
+
// same hole pathsFromDiff closes, one layer up. Off, git reports the delete and
|
|
475
|
+
// the add separately and both sides reach the classifier.
|
|
476
|
+
raw = execFileSync('git', ['diff', '--name-only', '--no-renames', `${base}...HEAD`], { encoding: 'utf8' })
|
|
477
|
+
} else return null
|
|
478
|
+
if (looksLikeDiff(raw)) return pathsFromDiff(raw)
|
|
479
|
+
return raw.split(/\r?\n/).map((s) => s.trim()).filter(Boolean)
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function main() {
|
|
483
|
+
const argv = process.argv.slice(2)
|
|
484
|
+
const cmd = argv[0]
|
|
485
|
+
const flags = {}
|
|
486
|
+
for (let i = 1; i < argv.length; i++) {
|
|
487
|
+
const a = argv[i]
|
|
488
|
+
if (a === '--json') flags.json = true
|
|
489
|
+
else if (a === '--stdin') flags.stdin = true
|
|
490
|
+
else if (a === '--diff') flags.diff = argv[++i]
|
|
491
|
+
else if (a === '--paths') flags.paths = argv[++i]
|
|
492
|
+
else if (a === '--config') flags.config = argv[++i]
|
|
493
|
+
else if (a === '--root') flags.root = argv[++i]
|
|
494
|
+
else { console.error(`scope-class: unrecognized flag "${a}"`); process.exit(2) }
|
|
495
|
+
}
|
|
496
|
+
const config = loadScopeClassConfigFromFile(flags.config, flags.root || process.cwd())
|
|
497
|
+
|
|
498
|
+
if (cmd === 'table') {
|
|
499
|
+
if (flags.json) console.log(JSON.stringify(config, null, 2))
|
|
500
|
+
else {
|
|
501
|
+
console.log('| class | patterns | oracle | high-risk |')
|
|
502
|
+
console.log('|---|---|---|---|')
|
|
503
|
+
for (const c of config.classes) {
|
|
504
|
+
console.log(`| ${c.id} | ${c.patterns.join(', ')} | ${c.oracle || `none — ${c.unprovenReason || 'UNDECLARED (blocking)'}`} | ${c.highRisk ? 'yes' : 'no'} |`)
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
process.exit(0)
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (cmd !== 'classify') {
|
|
511
|
+
console.error('usage: scope-class.mjs <classify|table> [--diff <base>|--stdin|--paths <file>] [--json] [--config <file>] [--root <dir>]')
|
|
512
|
+
process.exit(2)
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
const paths = readPaths(flags)
|
|
516
|
+
if (paths === null) { console.error('scope-class: classify needs one of --diff <base>, --stdin, --paths <file>'); process.exit(2) }
|
|
517
|
+
const result = classifyScope(paths, config)
|
|
518
|
+
const smoke = scopeSmokeReason(result)
|
|
519
|
+
const payload = { ...result, smokeNotApplicableReason: smoke, inapplicable: inapplicableArtifacts(result) }
|
|
520
|
+
|
|
521
|
+
if (flags.json) console.log(JSON.stringify(payload, null, 2))
|
|
522
|
+
else {
|
|
523
|
+
console.log(`scopeClass: ${result.scopeClass}${result.highRisk ? ' highRisk: true (auto-flag, raise-only)' : ''}`)
|
|
524
|
+
console.log(` ${result.reason}`)
|
|
525
|
+
for (const o of result.oracles) console.log(` oracle [${o.class}]: ${o.oracle}`)
|
|
526
|
+
for (const u of result.unproven) console.log(` unproven [${u.class}]: ${u.reason}`)
|
|
527
|
+
if (smoke) console.log(` smokeNotApplicableReason: ${smoke}`)
|
|
528
|
+
for (const row of payload.inapplicable) console.log(` ${row.artifact} → ${row.reason}`)
|
|
529
|
+
for (const f of result.findings) console.log(` ** BLOCKING (${f.code}): ${f.message}`)
|
|
530
|
+
}
|
|
531
|
+
process.exit(result.findings.length ? 1 : 0)
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
let launchedDirectly = false
|
|
535
|
+
let mainModuleError = null
|
|
536
|
+
try {
|
|
537
|
+
const { isMainModule } = await import('../../engineering-runtime/scripts/main-module.mjs')
|
|
538
|
+
if (typeof isMainModule !== 'function') throw new Error('main-module.mjs does not export isMainModule')
|
|
539
|
+
launchedDirectly = isMainModule(import.meta.url)
|
|
540
|
+
} catch (error) {
|
|
541
|
+
mainModuleError = error
|
|
542
|
+
try {
|
|
543
|
+
launchedDirectly = fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url))
|
|
544
|
+
} catch {
|
|
545
|
+
launchedDirectly = false
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
if (launchedDirectly && mainModuleError) {
|
|
550
|
+
console.error(`scope-class: cannot load engineering-runtime main-module helper: ${mainModuleError.message}`)
|
|
551
|
+
process.exitCode = 1
|
|
552
|
+
} else if (launchedDirectly) {
|
|
553
|
+
main()
|
|
554
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harness-runtime
|
|
3
|
+
description: Internal import-only library shared by first-party engineering packages. Not a workflow skill; never select or invoke it as a user capability.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
user-invocable: false
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Harness Runtime
|
|
9
|
+
|
|
10
|
+
This support-only runtime package exposes shared programmatic contracts plus canonical model discovery and model-catalog utilities. It ships the team catalog baseline; per-harness user files carry only explicit confirmed overrides. It has no user or model-invocable workflow.
|
|
11
|
+
|
|
12
|
+
## Package Map
|
|
13
|
+
|
|
14
|
+
- `contracts.md` defines the neutral values, planner boundary, discovery handoff, and topology rules.
|
|
15
|
+
- `native-question-contracts.md` pins the Pi, Codex, and Claude Code adapter schemas and response behavior.
|
|
16
|
+
- `index.mjs` exports neutral constructors plus pure question planning and response normalization.
|
|
17
|
+
- `discover-models.mjs` enumerates model evidence; `model-catalog.mjs` manages per-harness classifications.
|
|
18
|
+
- `references/model-catalog.md` documents catalog policy; `bin/` contains the installed command wrappers.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Harness runtime contracts
|
|
2
|
+
|
|
3
|
+
`index.mjs` exports four neutral constructors: `defineCurrentTurnCapabilities`, `defineQuestionSpec`, `defineQuestionAnswers`, and `defineModelAvailability`. It also exports the pure adapter layer, `planStructuredQuestions` and `normalizeQuestionResponses`. Model enumeration and persistence are separate entrypoints in `discover-models.mjs` and `model-catalog.mjs`; they are not re-exported from `index.mjs`.
|
|
4
|
+
|
|
5
|
+
The runtime accepts current-turn capabilities as explicit input. It never infers native tools or spawn-model ids from training data or static configuration.
|
|
6
|
+
|
|
7
|
+
Question and answer values are harness-neutral immutable data. `planStructuredQuestions` selects only an advertised Pi, Codex, or Claude Code question tool, validates its native limits, orders recommendations, and emits deterministic payload batches. After all adapter-specific label and response-format transformations, each native representation must identify exactly one neutral stable option id; collisions fail before emission with structured `invalid-question` details. `normalizeQuestionResponses` maps unique native labels and custom text back to frozen `{ questionId: answers[] }` values and rejects duplicate mappings instead of choosing one. See `native-question-contracts.md` for the pinned schemas, adapter rules, response fixtures, and cancellation behavior.
|
|
8
|
+
|
|
9
|
+
Model discovery unions explicit current-turn spawn ids and human-named runnable ids with configured or credentialed evidence. Its `{ discovered: [{ id, source }] }` output is evidence, not a neutral model-availability value: callers map each item to `{ id, sources: [source] }`, preserve `harness` and `completeness`, then pass that shape to `defineModelAvailability`; discovery `notes` remain operator diagnostics. Pi labels configuration discovery `full` even when it finds no runnable ids because its credential-aware configuration is the complete evidence class. Codex and Claude Code static configuration remains partial unless current-turn or runtime-enumeration evidence completes it. Catalog writes remain isolated to each harness's user directory, and the installation-relative team seed is read-only.
|
|
10
|
+
|
|
11
|
+
Shell code cannot invoke a native question tool inside the agent's current turn. It may validate and plan data; the agent performs each planned native tool call and passes the responses back for normalization.
|
|
12
|
+
|
|
13
|
+
When no supported native question tool is advertised, concise free-text input is permitted only for one optionless question. Textual multiple-choice emulation is forbidden. Unsupported multi-select and all secret input fail explicitly rather than degrading silently.
|
|
14
|
+
|
|
15
|
+
Model discovery and catalog persistence remain separate from question planning. Current-turn tool availability is never inferred from model or harness configuration. Source-tree imports outside `skills/engineering` are unsupported until an installation-aware adapter entrypoint exists; consumers must not copy the runtime to work around that boundary.
|