Repository navigation
Releases: raccioly/testguard
Release list
TestGuard v0.18.3
Automated weekly release — everything merged since v0.18.2.
Changed
- chore(homebrew): sha256 for v0.18.2 (#202)
TestGuard v0.18.2
Automated weekly release — everything merged since v0.18.1.
Changed
- perf: use one fresh process for single-entry native probes (#200)
- perf: focus gate annotation and claim selection defenders (#198)
- chore(homebrew): sha256 for v0.18.1 (#197)
Performance
- Eligible single-file native Node confirmations use one fresh process, avoiding a second process launch while preserving real CLI entry identity, ordinary tests beside
.only, import and late-error refusals, budgets, and process cleanup. Discovery, multiple files and older runtimes keep the existing isolated route. - Focus gate coverage, repeated claim selection and annotation ID bounds defenders on their relevant checks, retaining all original assertions in the mandatory acceptance suite and all fault recipes.
TestGuard v0.18.1
Automated weekly release — everything merged since v0.18.0.
Changed
- test: consolidate native runtime acceptance checks
- perf: isolate native admission mutation defenders
- perf: size bounded report buffers to observed files
- chore(homebrew): sha256 for v0.18.0 (#194)
Changed
- Runner report and discovery-config reads reserve memory for the observed
file size instead of the maximum allowed size, retaining the hard byte
ceiling and checking file growth before parsing. - Native-runner admission self-probes use focused defenders, preserving the
fault recipes and full runner acceptance coverage while avoiding unrelated
timeout and process-cleanup checks for each admission confirmation.
TestGuard v0.18.0
Automated weekly release — everything merged since v0.17.0.
Changed
- Merge branch 'main' into dependabot/github_actions/all-actions-d5b8684899
- feat: native Node probes with measured startup savings (#192)
- chore(homebrew): sha256 for v0.17.0 (#191)
- chore(deps): bump actions/cache
Added
- Explicit
--runner node-testsupport for plain JavaScript projects using
Node's built-in test framework, with native entry-file discovery, fresh
process confirmations and bounded structured reports. No runner is installed
and existing automatic runner selection is unchanged.
TestGuard v0.17.0
Automated weekly release — everything merged since v0.16.0.
Changed
- feat: integrate adoption guidance and machine-safe probing (#189)
- chore(deps-dev): bump vitest from 5.0.1 to 5.0.2 in the all-npm group (#187)
- chore(homebrew): sha256 for v0.16.0 (#186)
Added
-
Unannotated scaffold defaults use unfinished
TODO-CLAIM-Nidentifiers rather than file/function-shaped claim names. Allocation avoids supplied IDs; explicit IDs/annotations and existing evidence remain unchanged, while sweep pooling preserves distinct candidates. -
Read-only
scaffold --from-document <local-text-path>and--from-fix <full-commit-ID>inspection, backed by the closedauthoring-inputreport contract. Validation retains historical partition counts and rejects unsafe/private paths, inconsistent identities and optimistic verification labels. Stdout-only output emits no document text or claims; input inspection requires independent intent and is not verification. -
Explicit
scaffold <source...> --into <existing-draft.json> --claim <ID>appends mechanically proposed faults while preserving supplied intent and existing faults.--jsonpreviews without writes; ordinary scaffold remains compatible. Draft updates use bounded admission, owned locking and private recovery, and refuse stale/unsafe inputs or unconfirmed writes rather than claiming verified coverage. -
Sweep keeps equal-basename and repeated-annotation drafts distinct before selection, assigning collision-free pooled claim IDs without changing fault content, metadata or defenders.
-
New mechanical scaffold drafts declare
inferredorigin and ask for intended observable behavior from a requirement, ADR, bug or incident. CLI/status/skill guidance explains the source handoff without authenticating references or promoting annotations/tests into independent intent. Existing supplied scaffold metadata is preserved. -
Explicit
probe --require-origin <kinds>checks declared origins on complete confirmed current-project probes, rechecks native universe and file bindings, and reports failed/unavailable policy without suppressing survivors through baselines or severity floors. Kinds do not authenticate independence; custom/static universes are unavailable. Offline status audits current declarations without certifying freshness; brief retains labeled recorded-run policy before caps and filtering. -
Candidate evidence/status/brief schemas accept a closed optional declared-origin policy result, with unsuppressed fault identities, refusal reasons, consistent states and probe exit codes. This is an audit contract, not authenticated independence.
-
Claim sources share a closed origin vocabulary across claims and evidence, adding
doc,bug,incident,reviewandinferred. Status reports current declared origins; evidence and briefs summarize all recorded origins before filtering/caps, separating distinct claims from records and reporting conflicting declarations. Human output labels these as unauthenticated declarations. Labels do not change default gates; origin policy requires explicit selection. -
Claims/status missing-source-link advisories identify distinct claim IDs and suggest read-only annotation preview without changing verification state, next action or exit codes; annotation-sourced claims retain their existing drift error.
-
Explicit
claims --annotateread-only file-header preview and--applyauthoring for JavaScript/TypeScript and Python, with claim selection, bounded all-target admission, owned locking, private recoverable originals and truthful partial-failure reporting. Authoring JSON uses a closedannotationscontract; placement is not verification or authentication of intent.
Fixed
-
Clarify that cold probes and changed discovery/configuration can require full verification; unchanged target and defender files alone do not guarantee a cheap CI run.
-
Status marks evidence stale when a recorded automatic-discovery dependency (including a negative candidate, barrel or resolver config) changes or becomes unavailable. Previously unchanged defender lists could hide this drift. Native test-universe policy freshness remains pending.
-
Annotation scanning and placement ID admission avoid excessive regex backtracking on long alphanumeric tokens without a hyphen; status advice uses bounded, failure-aware scanning so unrelated source failures cannot prevent its verification decision.
-
Claim statement, severity, source and producer edits now invalidate cached probe evidence and appear as stale in status. Old kills cannot silently carry an edited requirement or provenance declaration.
Changed
- Reduce repeated self-probe setup with focused defenders for 40 existing fault checks, retaining the complete native integration regressions, all 327 fault recipes, three-run confirmation and existing cost budgets.
- Bound built-in runner concurrency to one worker by default, with
--workersoverrides, and cap outer regression workers at two (one on a two-core machine). - Drain noisy runner stdout, bound diagnostics and report reads, and terminate owned runners before restoring mutations and scratch worktrees on cancellation.
- Run the project-pinned Playwright CLI directly instead of spawning npm for each confirmation, and reset Python interpreter caches at measurement boundaries.
- Record actual probe elapsed time and unique fresh runner invocations separately from historical attributed costs; preserve all confirmation and cost gates, and invalidate reuse when native worker policy changes.
TestGuard v0.16.0
Automated weekly release — everything merged since v0.15.1.
Changed
- feat: fault-specific defenders, provenance and cost reporting (#184)
- Add advisory AI update guidance and stabilize cleanup regression (#183)
- chore(homebrew): sha256 for v0.15.1 (#182)
Added
- Fault-specific
defendedByoverrides, with explicit empty-list discovery,
evidence selection provenance, per-fault cost reporting and prior-kill
narrowing warnings (#90). Selection changes invalidate reuse and status;
admission and changed-file coverage use the actual selected defenders.
Changed
- New AI integrations include permission-aware, once-per-session update advice
that identifies the actual CLI and requests approval before any upgrade.
CLI commands and session-start hooks remain offline. Existing customized
instructions remain untouched; safe manual refresh is documented.
Fixed
- The daemon-cleanup regression test now requires explicit startup and
post-cleanup release signals instead of assuming a detached process starts
and writes within fixed sleeps. Timeout and cleanup semantics are unchanged.
TestGuard v0.15.1
Automated weekly release — everything merged since v0.15.0.
Changed
- fix: runner timeout identity and reported adoption regressions (#180)
- chore(homebrew): sha256 for v0.15.0 (#177)
Fixed
- Assertion messages quoting "timed out" no longer become runner timeouts.
Native timeout headers and structured timeout failures remain non-detections
(#179). - Configuration dependency hashing no longer rejects harmless absolute-looking
strings such as Vite URL bases, middleware routes, orsplit('/'). Existing
outside-project file dependencies and symlinks still fail closed (#178). - Discovery failures no longer assert that dependencies are missing when the
runner resolved successfully but its configuration could not be discovered. - Each subcommand's
--helpnow shows its own options and an example; global
--helpexits successfully and points to command-specific help (#120). - Parent gates, status change reports, and claimed-surface counts respect valid
nested TestGuard project boundaries. Delegated files are explicitly reported
and require a separate child gate; invalid or symlinked markers fail (#150).
Added
- Explicit
probe --allow-emptyadoption mode, also available as an opt-in
GitHub Action input. A valid empty claims file skips verification without
writing evidence; JSON keeps theno-claimsstate. Default empty probes,
invalid claims, and explicit claim selections still fail (#176).
TestGuard v0.15.0
Automated weekly release — everything merged since v0.14.2.
Changed
- feat: harden discovery, replay, and command budgets (#174)
- chore(homebrew): sha256 for v0.14.2 (#173)
Added
- Runner-native test discovery for Vitest, Jest, and Playwright, with bounded
output, path validation, immutable universe manifests, exact mixed-runner
routing, and configuration-closure hashes (including workspace configs,
package helpers, setup files, and Python collection hooks) that prevent stale
evidence reuse. - Symbol-aware JavaScript/TypeScript defender discovery through named,
default, namespace, CommonJS, and barrel re-exports. Ambiguity and bounded
resolver exhaustion fail closed asdefender-discovery-indeterminate. probe,sweep, andreplayaccept--command-budget <ms>as a
cooperative measurement deadline distinct from the existing per-run
--budget. It caps asynchronous children and is checked at stage and write
boundaries; synchronous setup may overrun but cannot publish a partial
result, so an unattempted suffix can never be reported as clean.
Fixed
- Runner timeouts now hard-kill the original process group and descendants
still attributable at timeout. Diagnostics explicitly say cleanup is
unverified because a previously reparented daemon requires external OS or
container containment. - Generated CommonJS export mutations and unresolved symbol/configuration
paths fail closed instead of allowing a falsenocoverresult. - Dirty-tree preflight now resolves the same full primary-plus-owned runner
universe as measurement, including custom Playwright names and imported
configuration helpers; discovery failure blocks rather than hiding edits.
TestGuard v0.14.2
Automated weekly release — everything merged since v0.14.1.
Changed
- chore(homebrew): sha256 for v0.14.1 (#171)
TestGuard v0.14.1
Automated weekly release — everything merged since v0.14.0.
Changed
- fix: four defects that made
nocoverreport discovery failures as findings (#169) - chore: untrack local agent tooling and a generated fixture artifact (#168)
- chore(homebrew): sha256 for v0.14.0 (#167)
- docs(brief): page 6 carries what 0.14.0 changed there (#166)
Fixed
-
sweepno longer refuses to write after a sweep that learned nothing.
learnedProductivitynamed every evidence document it read as an ordering
source, whileobservedcounts onlykilledandsurvivedrecords. A
document whose records are allnocover— the ordinary shape of a first
sweep — therefore producedsources: [...]withobserved: 0, which the
sweep validator correctly refuses. Because that document is written to
.testguard/sweep-evidence.json, every later sweep failed the same way,
permanently, until someone deleted a gitignored file nothing mentioned. An
ordering now names only the documents that contributed an observation, which
is what "the documents it was learned from" always meant. Measured on an
external corpus: this fired on 10 of 34 sweep invocations. -
replayresolves Python importers with the Python resolver.
replaymatched test files against a reverted source file with the
JavaScript importer for every language.from pkg.mod import xcarries no
quoted specifier, so nothing ever matched, the defender set was always empty
for Python, and every Python verdict wasnocover— "no test imports the
reverted source" — however complete the suite.discoverDefendersDetailed
has always branched on the target's language;replaynow does the same. -
A runner that matches no test file is no longer selected silently.
--runner autotries vitest, jest, then python. A TypeScript project on
Playwright resolves neither JavaScript runner, soautoreached python
wherever apython3existed, globbed for.py, found none, and reported
every fault asnocover.autonow prefers a resolvable runner that can see
test files, and when none can it says so (no runner matched a test file … every verdict will be nocover) instead of letting discovery's failure read
as a finding about the project. An explicitly named--runneris still
honoured; every selection now reportstestFiles. -
replayno longer reportsnocoverwhen it removed the only test file.
Removing the fix's own test removes the whole FILE, and on a project with
few, large test files that also removes tests which pre-dated the fix and
might have caught the bug. Nothing is left to run, so nothing can be
concluded: the verdict is nowunverifiablewith reason
the-fix-shipped-the-only-test-file.nocoveris a statement about the
PROJECT — "no test exercises this" — and it enters the calibration as a
miss, so the old behaviour charged a project for evidence the measurement
itself destroyed. The validator now refuses the mislabelled form, and
GATE-SEMANTICS.mdcarries it as a third rule beside de-duplication and
test removal.
Changed
- Python: a module-level dunder assignment is no longer proposed as a
fault.__version__,__all__and__author__at module level are
metadata nobody writes a test for, so a survivor on one teaches the
survival-learned ordering to prefer a barren class — the same reasoning that
already sets a presentational JSX element aside. Narrow on purpose: a
module-level constant such asDEFAULT_MAX_SIZE = 100is still proposed,
because removing a real default changes a real default.
Changed
- The brief's page 6 says what 0.14.0 changed there: the evidence now names
the mocked layer and the assertion shape beside a save-path survivor's
verdict, and the fourth rule of the lower rungs — whatever a sweep does not
probe, it counts, presentational elements included. Re-rendered; still eight
sheets from eight pages.