testguard-cli 0.4.0__tar.gz → 0.6.0__tar.gz
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.
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.github/scripts/sync-release-version.mjs +3 -0
- testguard_cli-0.6.0/.github/workflows/ci.yml +260 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.gitignore +2 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.pre-commit-hooks.yaml +9 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/AGENTS.md +4 -2
- testguard_cli-0.6.0/CHANGELOG.md +532 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/CONTRIBUTING.md +1 -1
- testguard_cli-0.6.0/PKG-INFO +552 -0
- testguard_cli-0.6.0/README.md +528 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/action.yml +19 -2
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/bench/README.md +19 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer/README.md +3 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer/expected.json +12 -0
- testguard_cli-0.6.0/fixtures/known-answer/test/export-mocked.test.mjs +13 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer/testguard.claims.json +69 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer-jest/expected.json +4 -0
- testguard_cli-0.6.0/fixtures/known-answer-jest/test/export-mocked.test.js +11 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer-jest/testguard.claims.json +27 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/.gitignore +4 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/README.md +30 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/e2e/flaky.spec.mjs +16 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/e2e/toggle.spec.mjs +16 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/expected.json +31 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/package-lock.json +1214 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/package.json +12 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/playwright.config.mjs +11 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/src/toggle.mjs +15 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/test/toggle.test.mjs +10 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/test-results/.last-run.json +4 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/testguard.claims.json +185 -0
- testguard_cli-0.6.0/fixtures/known-answer-playwright/vitest.config.mjs +1 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/package-lock.json +2 -2
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/package.json +1 -1
- testguard_cli-0.6.0/packaging/gitlab/testguard.gitlab-ci.yml +120 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/packaging/homebrew/testguard.rb +1 -1
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/pyproject.toml +1 -1
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/GATE-SEMANTICS.md +109 -1
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/README.md +4 -2
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/examples/claims.json +24 -0
- testguard_cli-0.6.0/spec/conformance/examples/evidence.json +579 -0
- testguard_cli-0.6.0/spec/conformance/examples/gate.json +38 -0
- testguard_cli-0.6.0/spec/conformance/examples/replay.json +59 -0
- testguard_cli-0.6.0/spec/conformance/invalid/evidence.annotated-signal-without-reason.json +548 -0
- testguard_cli-0.6.0/spec/conformance/invalid/evidence.byrunner-file-not-resolved.json +560 -0
- testguard_cli-0.6.0/spec/conformance/invalid/evidence.contention-without-runners.json +574 -0
- testguard_cli-0.6.0/spec/conformance/invalid/evidence.discovered-defender-mocks-subject.json +552 -0
- testguard_cli-0.4.0/spec/conformance/examples/evidence.json → testguard_cli-0.6.0/spec/conformance/invalid/evidence.ignored-dirty-on-snapshot.json +4 -1
- testguard_cli-0.6.0/spec/conformance/invalid/gate.counts-disagree.json +20 -0
- testguard_cli-0.6.0/spec/conformance/invalid/gate.exit-zero-with-uncovered.json +20 -0
- testguard_cli-0.6.0/spec/conformance/invalid/gate.ignore-cover-without-pattern.json +20 -0
- testguard_cli-0.6.0/spec/conformance/invalid/replay.blind-with-a-failing-run.json +20 -0
- testguard_cli-0.6.0/spec/conformance/invalid/replay.duplicate-patch-id.json +26 -0
- testguard_cli-0.6.0/spec/conformance/invalid/status.claim-without-file.json +29 -0
- testguard_cli-0.6.0/spec/conformance/invalid/status.unclaimed-hidden-behind-unproven.json +40 -0
- testguard_cli-0.6.0/spec/lib/validate.mjs +206 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/schemas/baseline.schema.json +8 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/schemas/brief.schema.json +11 -1
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/schemas/common.schema.json +32 -1
- testguard_cli-0.6.0/spec/schemas/evidence.schema.json +549 -0
- testguard_cli-0.6.0/spec/schemas/gate.schema.json +52 -0
- testguard_cli-0.6.0/spec/schemas/replay.schema.json +85 -0
- testguard_cli-0.6.0/spec/schemas/status.schema.json +334 -0
- testguard_cli-0.6.0/src/admit/admit.mjs +17 -0
- testguard_cli-0.6.0/src/baseline/baseline.mjs +63 -0
- testguard_cli-0.6.0/src/brief/brief.mjs +177 -0
- testguard_cli-0.6.0/src/claims/removed.mjs +161 -0
- testguard_cli-0.6.0/src/cli.mjs +194 -0
- testguard_cli-0.6.0/src/commands/admit.mjs +116 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/commands/baseline.mjs +17 -3
- testguard_cli-0.6.0/src/commands/brief.mjs +48 -0
- testguard_cli-0.6.0/src/commands/claims.mjs +59 -0
- testguard_cli-0.6.0/src/commands/gate.mjs +47 -0
- testguard_cli-0.6.0/src/commands/init.mjs +28 -0
- testguard_cli-0.6.0/src/commands/mcp.mjs +12 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/commands/probe.mjs +12 -3
- testguard_cli-0.6.0/src/commands/replay.mjs +63 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/commands/status.mjs +4 -1
- testguard_cli-0.6.0/src/gate/changed.mjs +222 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/git.mjs +5 -0
- testguard_cli-0.6.0/src/init/init.mjs +235 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/init/templates/SKILL.md +21 -3
- testguard_cli-0.6.0/src/mcp/server.mjs +104 -0
- testguard_cli-0.6.0/src/mcp/tools.mjs +114 -0
- testguard_cli-0.6.0/src/probe/contention.mjs +60 -0
- testguard_cli-0.6.0/src/probe/discover.mjs +21 -0
- testguard_cli-0.6.0/src/probe/independence.mjs +59 -0
- testguard_cli-0.6.0/src/probe/mocks.mjs +120 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/probe/probe.mjs +126 -18
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/probe/rank.mjs +73 -15
- testguard_cli-0.6.0/src/probe/runners/index.mjs +64 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/probe/runners/jest.mjs +3 -3
- testguard_cli-0.6.0/src/probe/runners/playwright.mjs +133 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/probe/runners/shared.mjs +70 -13
- testguard_cli-0.6.0/src/probe/runners/vitest.mjs +8 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/render.mjs +2 -2
- testguard_cli-0.6.0/src/replay/label.mjs +64 -0
- testguard_cli-0.6.0/src/replay/replay.mjs +309 -0
- testguard_cli-0.6.0/src/scaffold/producers.mjs +296 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/scaffold/scaffold.mjs +9 -3
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/status/status.mjs +88 -7
- testguard_cli-0.6.0/test/admit.test.mjs +125 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/baseline.test.mjs +30 -1
- testguard_cli-0.6.0/test/brief.test.mjs +144 -0
- testguard_cli-0.6.0/test/claims-since.test.mjs +150 -0
- testguard_cli-0.6.0/test/contention.test.mjs +59 -0
- testguard_cli-0.6.0/test/discover.test.mjs +55 -0
- testguard_cli-0.6.0/test/gate.test.mjs +227 -0
- testguard_cli-0.6.0/test/gitlab-template.test.mjs +47 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/glob.test.mjs +15 -2
- testguard_cli-0.6.0/test/independence.test.mjs +100 -0
- testguard_cli-0.6.0/test/init.test.mjs +234 -0
- testguard_cli-0.6.0/test/mcp.test.mjs +222 -0
- testguard_cli-0.6.0/test/mocks.test.mjs +67 -0
- testguard_cli-0.6.0/test/probe-preconditions.test.mjs +63 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/probe.fixture.test.mjs +38 -6
- testguard_cli-0.6.0/test/probe.playwright.test.mjs +73 -0
- testguard_cli-0.6.0/test/release-sync.test.mjs +57 -0
- testguard_cli-0.6.0/test/replay.test.mjs +391 -0
- testguard_cli-0.6.0/test/runner-playwright.test.mjs +170 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/runner-vitest.test.mjs +53 -1
- testguard_cli-0.6.0/test/samples/playwright-report.json +295 -0
- testguard_cli-0.6.0/test/scaffold.test.mjs +300 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/status.test.mjs +91 -3
- testguard_cli-0.6.0/testguard.claims.json +1963 -0
- testguard_cli-0.6.0/testguard.ignore.json +41 -0
- testguard_cli-0.4.0/.github/workflows/ci.yml +0 -149
- testguard_cli-0.4.0/.testguard/baseline.json +0 -11
- testguard_cli-0.4.0/.testguard/status.json +0 -32
- testguard_cli-0.4.0/CHANGELOG.md +0 -241
- testguard_cli-0.4.0/PKG-INFO +0 -258
- testguard_cli-0.4.0/README.md +0 -234
- testguard_cli-0.4.0/spec/lib/validate.mjs +0 -132
- testguard_cli-0.4.0/spec/schemas/evidence.schema.json +0 -238
- testguard_cli-0.4.0/spec/schemas/status.schema.json +0 -110
- testguard_cli-0.4.0/src/baseline/baseline.mjs +0 -34
- testguard_cli-0.4.0/src/brief/brief.mjs +0 -89
- testguard_cli-0.4.0/src/cli.mjs +0 -137
- testguard_cli-0.4.0/src/commands/brief.mjs +0 -34
- testguard_cli-0.4.0/src/commands/claims.mjs +0 -30
- testguard_cli-0.4.0/src/commands/init.mjs +0 -15
- testguard_cli-0.4.0/src/init/init.mjs +0 -82
- testguard_cli-0.4.0/src/probe/discover.mjs +0 -12
- testguard_cli-0.4.0/src/probe/runners/index.mjs +0 -20
- testguard_cli-0.4.0/src/probe/runners/vitest.mjs +0 -7
- testguard_cli-0.4.0/src/scaffold/producers.mjs +0 -85
- testguard_cli-0.4.0/test/brief.test.mjs +0 -82
- testguard_cli-0.4.0/test/discover.test.mjs +0 -22
- testguard_cli-0.4.0/test/init.test.mjs +0 -57
- testguard_cli-0.4.0/test/probe-preconditions.test.mjs +0 -37
- testguard_cli-0.4.0/test/scaffold.test.mjs +0 -133
- testguard_cli-0.4.0/testguard.claims.json +0 -379
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.codex/hooks.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.gitattributes +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.github/dependabot.yml +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.github/scripts/install-smoke.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.github/workflows/auto-merge.yml +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.github/workflows/release.yml +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.github/workflows/scheduled-release.yml +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.github/workflows/supply-chain.yml +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.npmignore +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/.npmrc +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/CLAUDE.md +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/CODE_OF_CONDUCT.md +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/LICENSE +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/PRIVACY.md +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/SECURITY.md +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/SUPPORT.md +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/cli/testguard.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer/.gitignore +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer/package.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer/src/export.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer/src/redact.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer/test/flaky.test.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer/test/redact.test.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer/vitest.config.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer-jest/.gitignore +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer-jest/README.md +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer-jest/jest.config.js +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer-jest/package.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer-jest/src/export.js +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer-jest/src/redact.js +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer-jest/test/flaky.test.js +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/fixtures/known-answer-jest/test/redact.test.js +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/examples/baseline.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/examples/brief.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/examples/calibration.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/examples/evidence-provisional.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/examples/ignore.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/examples/status.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/baseline.bad-fingerprint-key.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/baseline.zero-count.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/brief.text-without-heading.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/brief.unknown-verdict-key.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/calibration.p-outside-ci.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/calibration.positives-exceed-n.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/claims.absolute-path.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/claims.duplicate-fault-id.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/claims.missing-provenance.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/claims.noop-fault.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/claims.occurrence-exceeds-hits.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/claims.parent-traversal.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/evidence.flaky-defender-without-flakiness.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/evidence.killed-by-non-assertion.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/evidence.killed-on-red-baseline.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/evidence.killed-without-n-runs.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/evidence.provisional-flag-on-confirmed-run.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/evidence.rank-extra-property.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/evidence.single-run-without-provisional.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/evidence.undeclared-killers-without-reason.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/evidence.unknown-verdict.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/evidence.unverifiable-without-reason.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/evidence.wrong-fingerprint.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/ignore.missing-reason.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/ignore.short-reason.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/status.clean-with-new-findings.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/invalid/status.write-test-without-target.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/conformance/schemas.test.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/lib/fingerprint.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/schemas/calibration.schema.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/schemas/claims.schema.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/spec/schemas/ignore.schema.json +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/claims/annotations.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/claims/load.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/commands/scaffold.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/evidence/writer.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/probe/classify.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/probe/inject.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/probe/worktree.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/util/glob.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/src/util/hash.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/annotations.test.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/classify.test.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/inject.test.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/probe.jest.test.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/rank-aliases.test.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/runner-command.test.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/snapshot.test.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/worktree.test.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/test/writer.test.mjs +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/testguard_cli/__init__.py +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/testguard_cli/wrapper.py +0 -0
- {testguard_cli-0.4.0 → testguard_cli-0.6.0}/vitest.config.mjs +0 -0
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* - pyproject.toml `version = "x.y.z"`
|
|
6
6
|
* - action.yml default of the `version` input
|
|
7
7
|
* - packaging/homebrew/*.rb the tarball URL (sha256 is set after publish)
|
|
8
|
+
* - packaging/gitlab/*.yml the include URL tag and the `version` input default
|
|
8
9
|
*
|
|
9
10
|
* `--check` verifies instead of writing (used by release.yml).
|
|
10
11
|
*/
|
|
@@ -21,6 +22,8 @@ const surfaces = [
|
|
|
21
22
|
['action.yml', /(\n version:\n description: [^\n]*\n required: false\n default: ')[^']*(')/, `$1${version}$2`],
|
|
22
23
|
['packaging/homebrew/testguard.rb', /testguard-cli-\d+\.\d+\.\d+\.tgz/g, `testguard-cli-${version}.tgz`],
|
|
23
24
|
['README.md', /raccioly\/testguard@v\d+\.\d+\.\d+/g, `raccioly/testguard@v${version}`],
|
|
25
|
+
['packaging/gitlab/testguard.gitlab-ci.yml', /testguard\/v\d+\.\d+\.\d+\/packaging/g, `testguard/v${version}/packaging`],
|
|
26
|
+
['packaging/gitlab/testguard.gitlab-ci.yml', /(\n version:\n description: [^\n]*\n default: ")\d+\.\d+\.\d+(")/, `$1${version}$2`],
|
|
24
27
|
];
|
|
25
28
|
|
|
26
29
|
let drift = 0;
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
name: TestGuard CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch: # manual recovery for pushes that don't auto-trigger (e.g. release PRs opened by GITHUB_TOKEN)
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
tags: ['v*'] # publish-check below runs on tags only
|
|
8
|
+
pull_request:
|
|
9
|
+
branches: [main]
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
test:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
strategy:
|
|
18
|
+
matrix:
|
|
19
|
+
# 20 is the floor (node:util.parseArgs). 24 ships npm 11 — keep it so
|
|
20
|
+
# `npm ci` exercises the npm that treats some config as fatal where
|
|
21
|
+
# npm 10 is silent. Do not drop 24.
|
|
22
|
+
node-version: [20, 22, 24]
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
26
|
+
with:
|
|
27
|
+
fetch-depth: 0 # probe builds a git worktree from HEAD; the self-probe below needs history
|
|
28
|
+
|
|
29
|
+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
30
|
+
with:
|
|
31
|
+
node-version: ${{ matrix.node-version }}
|
|
32
|
+
|
|
33
|
+
- name: Install
|
|
34
|
+
run: npm ci
|
|
35
|
+
|
|
36
|
+
# ── Syntax-check EVERY source, not just what the entry point eagerly
|
|
37
|
+
# imports; a lazily loaded module's parse error would otherwise slip. ──
|
|
38
|
+
- name: Syntax-check all sources
|
|
39
|
+
run: find cli src spec -name '*.mjs' -print0 | xargs -0 -n1 node --check
|
|
40
|
+
|
|
41
|
+
# ── Install-from-tarball smoke: the package must run as INSTALLED, with
|
|
42
|
+
# production dependencies only. 0.1.0 shipped unrunnable because the
|
|
43
|
+
# schema validator's dependency was a devDependency; the suite, which
|
|
44
|
+
# runs from the checkout, could not see it. ──
|
|
45
|
+
- name: Install smoke (pack → install --omit=dev → run)
|
|
46
|
+
run: npm run test:install
|
|
47
|
+
|
|
48
|
+
- name: Python wrapper imports (PyPI surface)
|
|
49
|
+
run: python3 -c "import testguard_cli.wrapper; print('testguard_cli.wrapper OK')"
|
|
50
|
+
|
|
51
|
+
# ── Test suite with a RUNTIME BUDGET. A test that walks the wrong tree
|
|
52
|
+
# or probes far more than it should still passes — it just takes
|
|
53
|
+
# forever. Only a duration gate catches that class. Normal: ~15s
|
|
54
|
+
# locally, ~30–60s here. Budget is loose on purpose. ──
|
|
55
|
+
- name: Run tests (with runtime budget)
|
|
56
|
+
shell: bash
|
|
57
|
+
env:
|
|
58
|
+
TEST_BUDGET_MS: 240000
|
|
59
|
+
run: |
|
|
60
|
+
START=$(date +%s%3N)
|
|
61
|
+
npm test
|
|
62
|
+
DURATION=$(( $(date +%s%3N) - START ))
|
|
63
|
+
echo "Test suite duration: ${DURATION}ms (budget: ${TEST_BUDGET_MS}ms)"
|
|
64
|
+
if [ "$DURATION" -gt "$TEST_BUDGET_MS" ]; then
|
|
65
|
+
echo "::error::Test suite took ${DURATION}ms, over the ${TEST_BUDGET_MS}ms budget — something is probing far more than it should."
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# ── Dogfood: the real binary against the known-answer fixture, as a
|
|
70
|
+
# user would run it (the suite drives main() in-process). ──
|
|
71
|
+
- name: CLI version
|
|
72
|
+
run: node cli/testguard.mjs --version
|
|
73
|
+
|
|
74
|
+
- name: claims — fixture lists cleanly, no drift
|
|
75
|
+
run: node cli/testguard.mjs claims fixtures/known-answer
|
|
76
|
+
|
|
77
|
+
- name: probe → baseline → probe → brief on the fixture (through the bin)
|
|
78
|
+
shell: bash
|
|
79
|
+
run: |
|
|
80
|
+
set -o pipefail
|
|
81
|
+
S=$(mktemp -d)
|
|
82
|
+
cp -R fixtures/known-answer/. "$S/"
|
|
83
|
+
rm -rf "$S/node_modules" "$S/.flake-counter" "$S/.testguard"
|
|
84
|
+
ln -s "$GITHUB_WORKSPACE/node_modules" "$S/node_modules"
|
|
85
|
+
git -C "$S" init -q
|
|
86
|
+
git -C "$S" -c user.email=ci@example.invalid -c user.name=ci add -A
|
|
87
|
+
git -C "$S" -c user.email=ci@example.invalid -c user.name=ci commit -qm fixture
|
|
88
|
+
B="$GITHUB_WORKSPACE/cli/testguard.mjs"
|
|
89
|
+
status=0; node "$B" probe "$S" --budget 60000 --quiet || status=$?
|
|
90
|
+
[ "$status" -eq 1 ] || { echo "::error::expected exit 1 (unproven claims), got $status"; exit 1; }
|
|
91
|
+
node "$B" baseline "$S"
|
|
92
|
+
status=0; node "$B" probe "$S" --budget 60000 --quiet || status=$?
|
|
93
|
+
[ "$status" -eq 0 ] || { echo "::error::expected exit 0 after baseline, got $status"; exit 1; }
|
|
94
|
+
node "$B" brief "$S" --text | head -12
|
|
95
|
+
# every verdict must appear exactly once per expected.json
|
|
96
|
+
node --input-type=module -e "
|
|
97
|
+
import { readFileSync } from 'node:fs';
|
|
98
|
+
const ev = JSON.parse(readFileSync('$S/.testguard/evidence.json','utf8'));
|
|
99
|
+
const exp = JSON.parse(readFileSync('fixtures/known-answer/expected.json','utf8')).expected;
|
|
100
|
+
const bad = ev.records.filter(r => exp[r.claim.id+'/'+r.subject.id].verdict !== r.verdict);
|
|
101
|
+
if (bad.length) { console.error('MISMATCH', bad.map(r => r.claim.id+'/'+r.subject.id+':'+r.verdict)); process.exit(1); }
|
|
102
|
+
console.log('fixture verdicts match expected.json:', ev.records.length);
|
|
103
|
+
"
|
|
104
|
+
|
|
105
|
+
- name: probe the jest fixture (through the bin, --runner jest)
|
|
106
|
+
shell: bash
|
|
107
|
+
run: |
|
|
108
|
+
S=$(mktemp -d)
|
|
109
|
+
cp -R fixtures/known-answer-jest/. "$S/"
|
|
110
|
+
rm -rf "$S/node_modules" "$S/.flake-counter" "$S/.testguard"
|
|
111
|
+
ln -s "$GITHUB_WORKSPACE/node_modules" "$S/node_modules"
|
|
112
|
+
git -C "$S" init -q && git -C "$S" -c user.email=ci@example.invalid -c user.name=ci add -A && git -C "$S" -c user.email=ci@example.invalid -c user.name=ci commit -qm fixture
|
|
113
|
+
status=0; node cli/testguard.mjs probe "$S" --runner jest --budget 60000 --quiet --no-escalate || status=$?
|
|
114
|
+
[ "$status" -eq 1 ] || { echo "::error::expected exit 1, got $status"; exit 1; }
|
|
115
|
+
node --input-type=module -e "
|
|
116
|
+
import { readFileSync } from 'node:fs';
|
|
117
|
+
const ev = JSON.parse(readFileSync('$S/.testguard/evidence.json','utf8'));
|
|
118
|
+
const exp = JSON.parse(readFileSync('fixtures/known-answer-jest/expected.json','utf8')).expected;
|
|
119
|
+
if (ev.run.runner.name !== 'jest') { console.error('runner was', ev.run.runner.name); process.exit(1); }
|
|
120
|
+
const bad = ev.records.filter(r => exp[r.claim.id+'/'+r.subject.id].verdict !== r.verdict);
|
|
121
|
+
if (bad.length) { console.error('MISMATCH', bad.map(r => r.claim.id+'/'+r.subject.id+':'+r.verdict)); process.exit(1); }
|
|
122
|
+
console.log('jest fixture verdicts match expected.json:', ev.records.length);
|
|
123
|
+
"
|
|
124
|
+
|
|
125
|
+
# ── The MCP server, driven as a client would: handshake, list, call.
|
|
126
|
+
# A harness-independent surface is only worth having if it actually
|
|
127
|
+
# speaks the protocol from a cold start. ──
|
|
128
|
+
- name: mcp — handshake, tools/list, tools/call over stdio
|
|
129
|
+
shell: bash
|
|
130
|
+
run: |
|
|
131
|
+
printf '%s\n' \
|
|
132
|
+
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
|
|
133
|
+
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
|
|
134
|
+
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
|
|
135
|
+
'{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"testguard_status","arguments":{"dir":"."}}}' \
|
|
136
|
+
| node cli/testguard.mjs mcp > "$RUNNER_TEMP/mcp.jsonl"
|
|
137
|
+
node --input-type=module -e "
|
|
138
|
+
import { readFileSync } from 'node:fs';
|
|
139
|
+
const msgs = readFileSync(process.env.RUNNER_TEMP + '/mcp.jsonl', 'utf8').trim().split('\n').map((l) => JSON.parse(l));
|
|
140
|
+
if (msgs.length !== 3) { console.error('expected 3 replies (the notification is never answered), got', msgs.length); process.exit(1); }
|
|
141
|
+
const [init, list, call] = msgs;
|
|
142
|
+
if (!init.result.protocolVersion) { console.error('no protocolVersion'); process.exit(1); }
|
|
143
|
+
if (list.result.tools.length !== 5) { console.error('expected 5 tools, got', list.result.tools.length); process.exit(1); }
|
|
144
|
+
if (!list.result.tools.every((t) => t.annotations.readOnlyHint)) { console.error('a tool is not marked read-only'); process.exit(1); }
|
|
145
|
+
if (call.result.isError) { console.error('status call failed:', call.result.content[0].text); process.exit(1); }
|
|
146
|
+
if (!call.result.structuredContent.next.action) { console.error('status carried no next action'); process.exit(1); }
|
|
147
|
+
console.log('mcp:', list.result.tools.map((t) => t.name).join(', '), '→ state', call.result.structuredContent.state);
|
|
148
|
+
"
|
|
149
|
+
|
|
150
|
+
# ── Every change needs a claim: the gate runs on this repository's own
|
|
151
|
+
# pull requests. A new source file without a claim (or an excusing
|
|
152
|
+
# ignore entry with a reason) turns the PR red. ──
|
|
153
|
+
# A claim that disappeared is invisible to every other check: `probe`
|
|
154
|
+
# verifies what is there, `gate` sees the file covered by another claim.
|
|
155
|
+
# Removal is allowed; it is never silent.
|
|
156
|
+
- name: claims — no claim or fault removed without a reason
|
|
157
|
+
if: github.event_name == 'pull_request'
|
|
158
|
+
run: node cli/testguard.mjs claims . --since "origin/${{ github.base_ref }}"
|
|
159
|
+
|
|
160
|
+
- name: gate — every changed source file carries a claim
|
|
161
|
+
if: github.event_name == 'pull_request'
|
|
162
|
+
run: node cli/testguard.mjs gate . --changed "origin/${{ github.base_ref }}"
|
|
163
|
+
|
|
164
|
+
# ── Self-verification: TestGuard is governed by the standard it defines.
|
|
165
|
+
# testguard.claims.json states invariants of the tool itself; every
|
|
166
|
+
# fault must be killed by the tool's own tests. Exit 0 = all defended. ──
|
|
167
|
+
# Runs on ONE Node leg: the verdicts do not depend on the Node minor,
|
|
168
|
+
# and each from-scratch probe is ~14 minutes. The previous run's
|
|
169
|
+
# evidence is restored from the cache so claims whose target and
|
|
170
|
+
# defenders did not change reuse their verdict (the tool's own
|
|
171
|
+
# reuse rule); only what changed is re-probed. No escalation in CI:
|
|
172
|
+
# a survivor here is a failure either way. ──
|
|
173
|
+
- name: Restore previous self-probe evidence (verdict reuse)
|
|
174
|
+
if: matrix.node-version == 22
|
|
175
|
+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
|
176
|
+
with:
|
|
177
|
+
path: .testguard/ci-self-evidence.json
|
|
178
|
+
key: self-evidence-${{ hashFiles('testguard.claims.json') }}-${{ github.sha }}
|
|
179
|
+
restore-keys: |
|
|
180
|
+
self-evidence-${{ hashFiles('testguard.claims.json') }}-
|
|
181
|
+
self-evidence-
|
|
182
|
+
|
|
183
|
+
- name: probe TestGuard's own claims
|
|
184
|
+
if: matrix.node-version == 22
|
|
185
|
+
run: node cli/testguard.mjs probe . --budget 180000 --no-escalate --out .testguard/ci-self-evidence.json
|
|
186
|
+
|
|
187
|
+
# A stable, branch-named artifact so a developer can fetch the evidence
|
|
188
|
+
# CI produced without knowing a run id (README: read CI's evidence
|
|
189
|
+
# locally). One Node leg is enough; the verdicts are identical.
|
|
190
|
+
- name: Upload evidence under a stable, branch-named artifact
|
|
191
|
+
if: always() && matrix.node-version == 22 && github.event_name == 'push'
|
|
192
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
193
|
+
with:
|
|
194
|
+
name: testguard-evidence-${{ github.ref_name }}
|
|
195
|
+
path: .testguard/ci-self-evidence.json
|
|
196
|
+
if-no-files-found: warn
|
|
197
|
+
|
|
198
|
+
- name: Upload self-probe evidence
|
|
199
|
+
if: always() && matrix.node-version == 22
|
|
200
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
201
|
+
with:
|
|
202
|
+
name: testguard-self-evidence
|
|
203
|
+
path: .testguard/ci-self-evidence.json
|
|
204
|
+
if-no-files-found: warn
|
|
205
|
+
|
|
206
|
+
# ── Playwright: the per-file runner is proven against its own browserless
|
|
207
|
+
# fixture, whose dependencies live in the fixture (never in the tool's
|
|
208
|
+
# package.json). Installed and run here only. ──
|
|
209
|
+
playwright:
|
|
210
|
+
runs-on: ubuntu-latest
|
|
211
|
+
steps:
|
|
212
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
213
|
+
with:
|
|
214
|
+
fetch-depth: 0
|
|
215
|
+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
216
|
+
with:
|
|
217
|
+
node-version: 22
|
|
218
|
+
cache: npm
|
|
219
|
+
cache-dependency-path: |
|
|
220
|
+
package-lock.json
|
|
221
|
+
fixtures/known-answer-playwright/package-lock.json
|
|
222
|
+
- name: Install (tool + fixture)
|
|
223
|
+
run: |
|
|
224
|
+
npm ci
|
|
225
|
+
npm ci --prefix fixtures/known-answer-playwright
|
|
226
|
+
- name: Playwright adapter units + mixed-defender acceptance
|
|
227
|
+
run: npx vitest run test/runner-playwright.test.mjs test/probe.playwright.test.mjs
|
|
228
|
+
- name: probe the playwright fixture through the bin (mixed defenders, auto runner)
|
|
229
|
+
shell: bash
|
|
230
|
+
run: |
|
|
231
|
+
set -o pipefail
|
|
232
|
+
S=$(mktemp -d)
|
|
233
|
+
cp -R fixtures/known-answer-playwright/. "$S/"
|
|
234
|
+
rm -rf "$S/node_modules" "$S/.flake-counter" "$S/.testguard" "$S/test-results"
|
|
235
|
+
ln -s "$GITHUB_WORKSPACE/fixtures/known-answer-playwright/node_modules" "$S/node_modules"
|
|
236
|
+
git -C "$S" init -q && git -C "$S" -c user.email=ci@example.invalid -c user.name=ci add -A && git -C "$S" -c user.email=ci@example.invalid -c user.name=ci commit -qm fixture
|
|
237
|
+
status=0; node cli/testguard.mjs probe "$S" --budget 60000 --quiet --no-escalate || status=$?
|
|
238
|
+
[ "$status" -eq 1 ] || { echo "::error::expected exit 1, got $status"; exit 1; }
|
|
239
|
+
node --input-type=module -e "
|
|
240
|
+
import { readFileSync } from 'node:fs';
|
|
241
|
+
const ev = JSON.parse(readFileSync('$S/.testguard/evidence.json','utf8'));
|
|
242
|
+
const exp = JSON.parse(readFileSync('fixtures/known-answer-playwright/expected.json','utf8')).expected;
|
|
243
|
+
const names = (ev.run.runners ?? []).map(r => r.name).sort().join(',');
|
|
244
|
+
if (names !== 'playwright,vitest') { console.error('runners were', names); process.exit(1); }
|
|
245
|
+
const bad = ev.records.filter(r => exp[r.claim.id+'/'+r.subject.id].verdict !== r.verdict);
|
|
246
|
+
if (bad.length) { console.error('MISMATCH', bad.map(r => r.claim.id+'/'+r.subject.id+':'+r.verdict)); process.exit(1); }
|
|
247
|
+
console.log('playwright fixture verdicts match expected.json:', ev.records.length);
|
|
248
|
+
"
|
|
249
|
+
|
|
250
|
+
# ── npm publish dry-run on tags ──
|
|
251
|
+
publish-check:
|
|
252
|
+
runs-on: ubuntu-latest
|
|
253
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
254
|
+
needs: test
|
|
255
|
+
steps:
|
|
256
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
257
|
+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
258
|
+
with:
|
|
259
|
+
node-version: 24
|
|
260
|
+
- run: npm publish --dry-run
|
|
@@ -8,6 +8,8 @@ coverage/
|
|
|
8
8
|
.testguard/evidence-provisional.json
|
|
9
9
|
.testguard/evidence-partial.json
|
|
10
10
|
.testguard/brief.json
|
|
11
|
+
.testguard/gate.json
|
|
12
|
+
.testguard/ci-self-evidence.json
|
|
11
13
|
.testguard/scaffold-*.json
|
|
12
14
|
# Local agent tooling — not part of the public project
|
|
13
15
|
.wolf/
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
# rev: v0.1.0
|
|
11
11
|
# hooks:
|
|
12
12
|
# - id: testguard-claims # fast: validates the claims file + drift
|
|
13
|
+
# - id: testguard-gate # fast: every changed source file must carry a claim
|
|
13
14
|
# - id: testguard-probe # slow: pre-push stage, runs the faults
|
|
14
15
|
#
|
|
15
16
|
# # install the push-stage hook once per clone:
|
|
@@ -23,6 +24,14 @@
|
|
|
23
24
|
pass_filenames: false
|
|
24
25
|
always_run: true
|
|
25
26
|
|
|
27
|
+
- id: testguard-gate
|
|
28
|
+
name: TestGuard gate (every change needs a claim)
|
|
29
|
+
description: Fails when a source file in this commit carries no claim, does not defend one, and is not excused by testguard.ignore.json. Fast; runs no tests.
|
|
30
|
+
entry: testguard gate --changed HEAD --include-dirty --quiet
|
|
31
|
+
language: node
|
|
32
|
+
pass_filenames: false
|
|
33
|
+
always_run: true
|
|
34
|
+
|
|
26
35
|
- id: testguard-probe
|
|
27
36
|
name: TestGuard probe (pre-push)
|
|
28
37
|
description: Injects every claim's faults and fails on any the tests miss. Gated by the committed baseline.
|
|
@@ -27,11 +27,13 @@ node cli/testguard.mjs scaffold src/probe/classify.mjs --json # what the produ
|
|
|
27
27
|
- `spec/schemas/common.schema.json` — verdicts, fault classes, provenance. The closed sets.
|
|
28
28
|
- `spec/lib/validate.mjs` — semantic rules (green baseline, N/N agreement, assertion-only kills, fingerprint derivation).
|
|
29
29
|
- `src/probe/classify.mjs` — the verdict function. Pure. Its check order *is* `GATE-SEMANTICS.md`.
|
|
30
|
+
- `src/probe/mocks.mjs` — mock-awareness: which candidate tests mock the target (never defenders), and the `mocked-never-asserted` signal. `src/probe/rank.mjs` resolves aliases (tsconfig `paths` through `extends`/`references`, vite/vitest `resolve.alias`, package.json `imports`).
|
|
30
31
|
- `src/probe/probe.mjs` — orchestrator: isolation → baseline (cached per defender set) → apply → probe → escalate → restore → classify → rank.
|
|
31
32
|
- `fixtures/known-answer/expected.json` — the oracle. Never edit it to match output.
|
|
32
33
|
- `testguard.claims.json` — claims about this codebase, probed in CI.
|
|
33
|
-
- `src/scaffold/producers.mjs` — the
|
|
34
|
-
- `src/probe/runners/` — one module per runner (`name`, `testGlobs`, `check`, `tests`, `run`) over `shared.mjs` (jest-compatible report parsing, budgeted process runner). A new runner needs its own fixture copy with
|
|
34
|
+
- `src/scaffold/producers.mjs` — the nine fault shapes. Deterministic line heuristics; no AST, no LLM. A new shape needs a synthetic-file test and a README row.
|
|
35
|
+
- `src/probe/runners/` — one module per runner (`name`, `testGlobs`, `check`, `tests`, `run`, optionally `owns` for a per-file runner) over `shared.mjs` (jest-compatible report parsing, budgeted process runner, pluggable `parse`/`env`). `playwright.mjs` is a per-file runner: it owns the files under its `testDir`; `index.mjs` partitions defenders by runner and merges their runs pessimistically. A new runner needs its own fixture copy with its own `expected.json`, verified by hand.
|
|
36
|
+
- `src/gate/changed.mjs` — claim coverage of a change (`gate --changed`). File-level, delta-only; an uncovered file exits 1; every ignore reliance is reported. Its rules are a section of `GATE-SEMANTICS.md`.
|
|
35
37
|
- `src/status/status.mjs` — the state machine every rendering derives from. A new state or action is a spec change (`status.schema.json`) and a skill-template change (`src/init/templates/SKILL.md`) in the same PR.
|
|
36
38
|
|
|
37
39
|
## Rules
|