Skip to content

Releases: schalermthai/redproof

Redproof plugin 0.3.0 — early access

Pre-release

Choose a tag to compare

@schalermthai schalermthai released this 20 Oct 10:09
b96d5b9

Redproof plugin releases

Independent of the Redproof npm library. Release versions are immutable.

0.3.0

  • Discover writes every answer for a reader new to Redproof, in chat as well as
    in files. It opens with the decision, defines Redproof terms once, and keeps
    internal status labels out of the prose.
  • Every discovery request except a time-boxed one produces a Markdown summary
    and an HTML report. The chat message summarises the handoff; it no longer
    replaces it.
  • The review page from the bundled helper is the only HTML report. Discover no
    longer writes its own HTML page.
  • Discover ranks recommendations by the uncovered gap. A promise that existing
    tests already guard stays visible as existing protection and is offered at most
    as a one-time proof. A top recommendation names the case no test exercises.
    Finding no uncovered case is a valid result.
  • design, build, challenge, review-pr, the review UI and the Stop hook are
    unchanged from 0.2.0.

Measured on a headless discover eval with Claude Sonnet 5.5 and Claude Opus 5.5
against pinned open-source repositories (ky, Express, Click, chi), with Express
and chi held out of every skill edit. Limitations: about one Sonnet
recommendation in eight still claims a case is untested when a test covers it.
Opus 5.5 was checked only on Express for the ranking change.

Redproof plugin 0.2.0 — early access

Pre-release

Choose a tag to compare

@schalermthai schalermthai released this 01 Oct 16:09
079faaf

Redproof plugin releases

Independent of the Redproof npm library. Release versions are immutable.

0.2.0

  • Claude Code Stop hook: runs the project's own redproof check when the agent
    ends a turn and keeps the turn open while a Gate fails.
  • The hook stays silent in projects without a Redproof config, checks only the
    configs that own changed files, and reports a check that could not run.
  • REFUSE reports remain unverified regardless of the configured CLI exit code.
  • A silent, bounded session-start check records pre-existing located Breaches;
    unchanged ones warn without blocking unrelated work. New or touched Breaches
    still block, and fixed failures lose their exemptions.
  • The five public skills and the review UI are unchanged from 0.1.0.

Limitations: Codex does not load hooks from this plugin. The hook needs git and
Node.js on the session's PATH; without Node the host reports a hook error and
nothing is checked. The hook was developed against Redproof 0.12.0 and runs the
library installed in the project; it does not install or upgrade one.

Redproof plugin 0.1.0 — early access

Pre-release

Choose a tag to compare

@schalermthai schalermthai released this 29 Sep 17:32
53811f3

Redproof plugin releases

Independent of the Redproof npm library. Release versions are immutable.

0.1.0

Initial early-access package. The GitHub release records publication status.

  • Five public skills: discover, design, build, challenge, review-pr.
  • Shared routing and review UI remain internal resources.
  • Discovery, design and build retain explicit human approval boundaries.
  • One canonical skill source, portable/Codex/Claude manifests and standalone UI.
  • Git-backed marketplace distribution with versioned snapshots.

Limitations: see the release readiness record before claiming host compatibility.
The instructions were developed against Redproof 0.12.0; that is not a promise
of compatibility with all library, adapter, model or host versions. Installation
does not install or upgrade the Redproof npm library.

Redproof 0.12.0

Choose a tag to compare

@schalermthai schalermthai released this 14 Sep 15:55
d4d4f80

Redproof turns a quality tool into a Gate: Rules, a Check that runs the real
tool, and Proofs that the Check catches the defect it claims to catch.

New Adapters

@redproof/knip turns unused code into a Gate. Seven Rules cover unused
files, exports, dependencies, development dependencies, undeclared
dependencies, unresolved imports, and duplicate exports. It runs Knip through a
bundled reporter, so the evidence is structured rather than parsed from text.

@redproof/istanbul turns test coverage into a Gate. nyc() collects
natively. istanbul() reads any producer of a full Istanbul coverage map, and
the repository proves that path with real c8. Four Rules cover statements,
branches, functions, and lines, each with a minimum percentage and optional
per-file enforcement. Counting, line semantics, and percentage truncation match
istanbul-lib-coverage exactly.

Both are first releases, so npm install finds them at 0.12.0.

Every Adapter now has a functional core

All six Adapter packages moved their decisions into src/core/ and their
effects into src/shell/ or the package entry point. Public exports did not
change.

Two dependency-cruiser rules enforce the split by path: an Adapter core cannot
import an effectful Node module, and it cannot import anything in its own
package outside src/core/. A third rule forbids one Adapter from importing
another. Each rule carries a proof that plants the violation and requires the
Gate to name it.

stryker() gained an optional second parameter, a mutation-run port. Existing
calls are unchanged. The port let five refusal paths gain end-to-end tests that
were previously unreachable.

New Rules

repository/lockfile-resolves-declared-optional-dependencies requires every
optional dependency a lockfile package declares to resolve to a lockfile entry.
A regenerated lockfile can silently drop the platform binaries for every
platform except the one that regenerated it. Nothing caught that before.

The self-hosted test-health Gate now collects {tests,packages/*/test}, the
same 86 files the test command runs. Thirteen package test files were read by
no Gate.

Fixes

  • ESLint directive notices no longer refuse a healthy project.
  • An allowed dependency-cruiser boundary disabled by allowedSeverity now
    REFUSES instead of passing silently.
  • Stryker adapter reporting, dependency-cruiser evidence handling, and ESLint
    evidence handling are each hardened.
  • Each published tarball is derived from the package it belongs to, so a
    per-package table can no longer pair a package with another package's
    tarball.
  • Publishable Adapter source cannot import the test kit.
  • npm publishing is resumable, and a new package's first publish explains its
    own bootstrap failure.

Verified

858 tests pass, 0 fail, 0 skipped. 6 Gates hold 38 Rules. 60 proofs established,
0 failed. All 8 packages pass clean-consumer verification at one shared version.

Redproof 0.11.0

Choose a tag to compare

@schalermthai schalermthai released this 10 Sep 04:36
48e5d85

What's Changed

Full Changelog: v0.10.0...v0.11.0

v0.10.0

Choose a tag to compare

@schalermthai schalermthai released this 08 Sep 01:18
d07f610

Stryker runs from a package directory

@redproof/stryker takes a cwd option, relative to the Gate root. Stryker runs from that directory, and configFile and Stryker's own relative paths resolve from it. The directory cannot leave the Gate root, lexically or through a symbolic link. A cwd that resolves outside refuses with stryker-cwd-outside-root. Real monorepos need this: a mutation-test target is usually one package, not the repository root.

Accepted-mutant baselines

@redproof/stryker gains a noNewUndetectedMutants Rule, id stryker/no-new-undetected-mutants. It reads a checked-in JSON array, acceptedMutantsFile, resolved from the working directory. Each entry names a mutant by file, full start and end location, mutator, and replacement. This is the same key Stryker uses in stryker-incremental.json, so an entry can be copied from that report.

The Rule matches identities, not counts. A new surviving mutant breaches even when the total survivor count is unchanged. Three cases refuse. A malformed, duplicate, or escaping entry refuses before Stryker runs, with stryker-accepted-mutants-invalid or stryker-accepted-mutants-outside-root. An accepted mutant that the tests now detect refuses with stryker-accepted-mutants-stale. An undetected mutant without a stable identity refuses with stryker-mutant-identity-unavailable, or stryker-mutant-identity-ambiguous when two mutants share one identity.

Select noNewUndetectedMutants in place of mutantsDetected. With both, every accepted mutant still breaches mutantsDetected.

Stryker temp files

The adapter runs Stryker with cleanTempDir: 'always'. A failing initial test run no longer leaves .stryker-tmp inside the Gate copy. Before this release that turned a REFUSE into an unrestored-workspace error during prove.

API

  • StrykerAdapterOptions.cwd?: string.
  • StrykerRuleOptions.noNewUndetectedMutants?: { acceptedMutantsFile: string }.
  • AcceptedStrykerMutant is exported.
  • The Known options list in the unknown-rule error now names three options.

v0.9.0

Choose a tag to compare

@schalermthai schalermthai released this 07 Sep 18:06
7831a76

Proof outcomes are states, not flags

A proof outcome now has one of three statuses. completed means the Check returned and the proof was judged. aborted means infrastructure failed before the Check returned, so there is no result. unrestored means the Check returned but the workspace did not return to its baseline, so there is a result and only a restoration error code.

The ok field is gone. proofEstablished(outcome) replaces it and is exported. A completed outcome is a union keyed by expected, and each proof kind has its own evaluation type. A proved RED always names its target. A GREEN proof cannot carry a RED-only reason. A verdict mismatch cannot report the verdict it expected.

Terminal and JSON prove output is unchanged.

Report Rules keep their breaches inside the breached state

RuleReportState puts the breaches inside the breached case as a NonEmptyList<Breach>. A held, unknown, or undecided Rule carries no list. The stored counts are gone; countBreachedRules(model) and countBreaches(model) replace them. RunSummary.breaches is a BreachTotal: exact with a count, or not-countable.

The JSON check report is unchanged.

Breaking API changes

  • InfrastructureProofOutcome is now AbortedProofOutcome | UnrestoredProofOutcome. status: 'error' is 'aborted' or 'unrestored'.
  • ok is removed from every outcome. Use proofEstablished(outcome).
  • ProofEvaluation is the union of RedProofEvaluation, GreenProofEvaluation, and RefuseProofEvaluation. proved.target is required on a RED.
  • RuleReport.breaches is removed. Read state.breaches when state.kind === 'breached'.
  • GateReportModel.breachedRules and breachCount are removed. Use countBreachedRules and countBreaches.
  • RunSummary.exactBreachCount is removed. Read breaches.kind.
  • baselineBlocksProof and baselineOutcome take a RedProof.

Skill

The redproof skill links the README and the docs by GitHub URL, so the links work after the skill is installed elsewhere.

v0.8.0

Choose a tag to compare

@schalermthai schalermthai released this 07 Sep 16:59

Prove reports say why

redproof prove now adds one indented line under each proof. A proved RED names the Rule that breached and what the Check said. A proved REFUSE names the refusal. A proof that did not prove says why: the wrong Rule breached, the Check passed, the verdict did not match, or the target was already breached before the mutation.

✓ no-todo / detects a TODO comment expected=red actual=fail
    breached source/no-todo: src/checkout.ts:12: TODO left in source
✗ lint / a var is flagged expected=red actual=fail
    target lint/no-var not breached; breached lint/no-let

The first line of each proof is unchanged. The JSON prove report adds reason and, under check, the breaches or the refusal in the shape the check report already uses. The report stays version 1, and the schema declares the new field.

API

  • CompletedProofOutcome gains a required reason: ProofEvaluation field. Code that builds outcomes by hand must set it. ok is unchanged.
  • ProofEvaluation is exported. A proved RED carries its target. A new kind, target-already-breached, marks a RED blocked by its baseline.

Self-hosting

The composition dependency Rule is now an allowlist: composition may import only composition, domain, and inspect.

v0.7.0

Choose a tag to compare

@schalermthai schalermthai released this 07 Sep 13:25

Behaviour changes

A wrong reporter option now prints one line and exits with 2, the same as every other usage mistake. Before, it printed a stack trace and exited with 1. This covers an unknown reporter name, a missing --reporter or --outputFile value, two reporters on stdout, and a prove reporter that prove does not support.

An unknown command is now reported before the config search. redproof lint says "Unknown command: lint" whether or not a config file exists.

API

  • renderRun and SourceExcerpts render the terminal report from values. formatRun still reads the source excerpts for you.
  • ReporterArgumentError is thrown by parseReporterArgs, so a caller can catch a bad reporter option by type.
  • The redproof/command subpath is unchanged. Its file moved to dist/command/index.js.

Structure

The package is now organised into bounded contexts, each with a pure core and an effectful shell: project, proof, workspace, run, command, inspect, reporter, cli, and composition. Every context exposes two surfaces, core/index.ts for other cores and index.ts for everyone else. The self-hosted architecture Gate guards both the purity of every core directory and the use of those surfaces, with 22 Rules and 27 proofs.

v0.6.0

Choose a tag to compare

@schalermthai schalermthai released this 06 Sep 19:10
877f0c8

Behaviour change

The default execution mode is now copies, not in-place.

Each Gate now works on its own copy, outside your project. A proof cannot touch
your real source tree, and Gates can run at the same time. To keep the old
behaviour, set it in redproof.config.ts:

export default defineConfig({
  execution: { mode: 'in-place' },
});

Fixes

  • Gate copies are created outside the project. A copy inside the project let
    tools such as ESLint find the project's own config by searching parent
    directories, so a refuse proof could report a false PASS.
  • The dependency-cruiser adapter now reads the JSON string that
    dependency-cruiser 18 returns. It previously refused every check.
  • The Stryker adapter no longer passes NODE_TEST_CONTEXT to the test suite it
    runs. An inherited value made a node --test child exit 0 on failure, so every
    mutant looked like it survived.

Packaging

  • Every package now ships a README, so the npm page is no longer blank.
  • redproof now ships the JSON reporter schemas under schema/.
  • Every package declares a top-level types field.