40 Commits
Author SHA1 Message Date
benbrownandGitHub b18faca993 Merge pull request #25 from bdbrown4/chore/mit-license
chore: relicense GPL-3.0-or-later → MIT
2026-08-04 09:24:21 -04:00
benbrownandClaude Fable 5 856b04dbba chore: relicense GPL-3.0-or-later -> MIT
Relicensed to make sharing and consumption frictionless — the skill is
meant to be dropped into arbitrary client repos, and MIT removes every
question a legal department would ask about that.

Clean to do unilaterally: git shortlog shows no third-party human
contributors (Ben Brown, Claude co-authoring Ben's sessions, and two
copilot-swe-agent[bot] workflow commits made at Ben's direction).

All living license surfaces swapped in lockstep: LICENSE (MIT text,
copyright 2026 Ben Brown), Cargo.toml workspace license, README, and the
skill frontmatter in both copies (.claude + .agents mirror, regenerated
byte-identical). Historical documents in results/ are records and keep
whatever they said at the time. Prior releases/clones under GPL-3.0
remain validly GPL-licensed at those commits, as always.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 09:18:21 -04:00
benbrownandGitHub 10a01acbdf Merge pull request #24 from bdbrown4/docs/detective-court
docs: name the statistical identity — Bayesian detective, frequentist court
2026-07-20 13:04:56 -04:00
benbrownandClaude Fable 5 24127bbcb4 docs: name the statistical identity — Bayesian detective, frequentist court
The two halves of the system run on opposite statistical philosophies, on
purpose, and until now the docs never said so. The optimizer is a Bayesian
detective: playbook prior, ledger evidence, policy ranking, explain
feedback — belief-updating that decides what to try next. The trust layer
is a frequentist court: equivalence gates, per-machine calibrated error
rates (A/A false-positive bound, injected-regression power bound), and a
CI-lower-bound accept rule with no prior anywhere on the accept path —
because its audience is a hostile reviewer who shares none of your priors.

The load-bearing edge is the return path: evidence flows from court to
detective (ledger rows + explain); authority never flows the other way.
Invariant, now stated in four places: priors steer where we look; they
never touch what we conclude. A wrong prior costs compute — each wasted
attempt honestly ledgered. A prior in the verdict would cost a false
claim, the one unrecoverable failure for a project whose product is trust.

- thesis.md: full section with the two-box diagram incl. the return edge,
  in docket order (equivalence before measurement); notes that estimated
  payoff is a belief and dollar figures are minted only by the mechanical
  report from accepted rows, and that even the learning layer bets on
  Wilson LOWER bounds — the detective is a pessimist too.
- README: the one-breath version, linking the full argument.
- SPEC §1: dated note mapping each half to its sections.
- CLAUDE.md: the mental model, one paragraph under Mission.

Framing credit: emerged from a design conversation on whether peltier is
"Bayesian engineering" — it is exactly half of one.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 12:52:44 -04:00
benbrownandGitHub ffc6674e13 Merge pull request #23 from bdbrown4/skill/explain-parity
skill: attempt mode points at explain for the next hypothesis
2026-07-20 10:11:40 -04:00
benbrownandClaude Fable 5 3946438fd6 skill: attempt mode points at explain for the next hypothesis
The attempt-mode guide predates crates/explain and stopped at the ROI
report. It now names the post-verdict step: run just explain on every
rejection before forming the next hypothesis — below-bar, null, and
regression are three different next moves the verdict string alone does
not distinguish. Advisory framing preserved (quote the record, not the
inferences). Mirror regenerated.

Verify mode needs nothing: consumer repos have no ledger, and its
read-it-honestly table already encodes the same narrative doctrine.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 10:05:41 -04:00
benbrownandGitHub c42a46cc92 Merge pull request #22 from bdbrown4/feat/explain
explain: post-verdict diagnostics — SPEC §3.7, crate, docs
2026-07-20 10:04:08 -04:00
benbrownandClaude Fable 5 444e5294fa explain: post-verdict diagnostics — SPEC §3.7, crate, docs
Verdicts say what; nothing said why. A rejection that reads only
rejected-bench teaches nothing, and the loop's compounding value is that
the next hypothesis is better than the last. This ships the teaching layer,
built so it can never contaminate the thing it explains.

New crate crates/explain (`just explain <run-id>`):

- Advisory, strictly off the accept path: runs after the verdict is
  recorded; nothing it emits feeds gates, bench, verdict, or ledger. Not
  agent-facing: harnessd stays at seven ops, by design (SPEC §3.7 says why
  - better hypotheses must never become a feedback channel into
  measurement).
- Ledger-only inputs, deterministic: consumes exactly one row via the new
  ledger::attempt_row; no config, no clock, no re-benching. Identical row,
  byte-identical text - proven live (cmp on two runs of a real row).
- Record vs inference is typographic: restatements print plain; anything
  beyond is prefixed `inference:` so an explanation can never be quoted as
  a measurement.
- The narrative must agree with the machine verdict. The first live run
  caught this class of bug: an accepted row without a recorded threshold
  was narrated as "a policy rejection" two lines under "verdict: accepted".
  Accepted rows are now always described by their CI lower bound (the
  defensible claim); rejected-bench rows classify against 1.0 (measured
  regression / null result / real-but-below-bar); NHR rows name the
  recorded cap and state the numbers were not the deciding factor;
  rejected-gate rows name the failing gate. Regression-tested.
- Historical rows are flagged, not laundered: accepted with
  sanitizers_clean=false prints the doctrine caution (comrak-010 shows it);
  fuzz_iters=0 accepts are named pre-integration rows.

verdict now records accept_threshold (the bar in force for that run) into
the bench env fingerprint, so rows are self-contained going forward -
explain never substitutes today's config for a historical bar, and says so
on older rows instead.

SPEC §3.7 (Added 2026-07-20) carries the invariants; book chapter
docs/src/explain.md shows real output from real rows (the accepted cJSON
win, the caught false-accept, the kernel-lane NHR); CLAUDE.md, README,
justfile, and the architecture layout updated (the layout also gains the
previously-omitted crates/policy line).

Verified: 21 workspace test suites green (6 new explain tests incl.
determinism and verdict-narrative agreement), clippy -D warnings clean,
fmt clean, mdbook builds, live runs against phase3-cjson-002,
phase5-matmul-opt, phase2-comrak-010, and phase4-cjson-service.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 09:53:14 -04:00
benbrownandGitHub 48ef299cec Merge pull request #21 from bdbrown4/skill/preflight-ps1
skill: cross-OS preflight — ps1 entry point, one CI-enforced contract
2026-07-16 08:44:49 -04:00
benbrownandClaude Fable 5 62df81709d skill: make the sh-vs-ps1 dispatch rule explicit
'Use whichever your host can launch' left the selection order implicit and
did not distinguish the two failure kinds. Now stated: dispatch on launcher
availability (not OS) — sh first, ps1 only when the sh launcher itself is
missing; and a STATUS=refuse from either entry point is final, never a cue
to try the other one for a different answer. The CI byte-diff exists
precisely so there is no different answer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 08:32:22 -04:00
benbrownandClaude Fable 5 b9fa4932b9 ci: the Windows refusal test failed because the refusal succeeded
GitHub's PowerShell step wrapper appends 'exit $LASTEXITCODE', so the
inner preflight's deliberate exit 1 — the exact outcome the step had just
asserted — leaked out as the step's own failure. Clear it with an explicit
exit 0 once the refusal is verified. The 5.1 log from the failing run shows
the ps1 behaving perfectly: STATUS=refuse, correctly composed em dash,
'unsupported host Windows' reason.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 08:20:49 -04:00
benbrownandClaude Fable 5 0f2020779e skill: cross-OS preflight — ps1 entry point, one CI-enforced contract
On a Windows host the preflight's job is to deliver a structured refusal
(measurement is Linux/POSIX-only). But a Windows-native harness with no
POSIX shell never got that far: preflight.sh fails to LAUNCH, and an agent
staring at "sh: not found" is exactly the agent that hand-rolls a timing
loop. The refusal doctrine has to be as portable as the skill.

- scripts/preflight.ps1: faithful port of the preflight contract, runs on
  Windows PowerShell 5.1 and pwsh 7+ on any OS. Host check first (so
  Windows refuses before touching anything), same walk-up resolution, same
  always-build rule, same key=value output, same exit codes. The source is
  pure ASCII with the shared em dashes composed at runtime — Windows
  PowerShell 5.1 misdecodes BOM-less UTF-8, and that exact bug class
  already bit this machine once (the francis-watchdog parse failure).
- Two implementations of one contract is a drift risk, so it is gated like
  every other claim in this repo: the skill-preflight CI job now runs BOTH
  scripts on the same ubuntu host and byte-diffs their stdout on all three
  paths (in-checkout resolve, no-checkout refusal, PELTIER_HOME from a
  foreign repo). Disagreement is a red build, not a footnote.
- New skill-preflight-windows job (windows-latest): asserts the native
  refusal end-to-end under Windows PowerShell 5.1 AND pwsh (STATUS=refuse,
  nonzero exit, the 'unsupported host' reason), plus Git Bash sh for good
  measure. Verified live on a real Windows 11 box before shipping: 5.1
  parses the pure-ASCII source clean and refuses with exit 1.
- SKILL.md / references/verify.md: document the second entry point ("use
  whichever your host can launch; never both, never neither"); book chapter
  and CLAUDE.md updated to match. .agents mirror regenerated (identical).
  The ZeroClaw variant is unaffected: rm -rf scripts/ drops the ps1 too,
  and its audit still passes (7 files scanned).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 08:15:43 -04:00
benbrownandGitHub c5531ed30c Merge pull request #20 from bdbrown4/docs/skill-chapter
docs: bring the book to parity with the skill; PR-gate the book build
2026-07-15 12:24:46 -04:00
benbrownandClaude Fable 5 6e169ab819 docs: bring the book to parity with the skill; PR-gate the book build
The cross-harness skill shipped (PR #17/#19) with README/CLAUDE.md/AGENTS.md
coverage, but the mdBook — the public disclosure surface — had zero mention
of it. By this project's own standard that is a parity defect: the flagship
consumable feature was undocumented where it is disclosed.

- New chapter "Consume it: the peltier skill" (docs/src/skill.md): install
  paths and the harness matrix, the ZeroClaw script-blocking variant, the
  gate order verify mode enforces, the refusal doctrine, and exactly which
  of these claims CI asserts. Numbers carry their CI and workload.
- SUMMARY.md, architecture.md (layout now lists the skill + mirror),
  reproduce.md, introduction.md: cross-links to the chapter.
- docs.yml: pull requests now BUILD the book (never deploy) — a broken
  chapter or dangling include is a red PR check, not a post-merge surprise.
  Also closes an audit finding: the book rebuilds when results/** changes,
  since case-study chapters {{#include}} evidence files from there.

Book build verified locally with mdbook 0.4.x (skill.html renders).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 12:19:49 -04:00
benbrownandGitHub c2d80f95d8 Merge pull request #19 from bdbrown4/skill/cross-harness
skill: make the peltier skill consumable across agent harnesses
2026-07-15 12:06:18 -04:00
benbrownandClaude Fable 5 7c2177c5c6 skill: executable bit on the mirrored preflight.sh
The .agents mirror staged preflight.sh as a new path, so it missed the
canonical copy's 755. diff -r compares content, not modes — index modes
must match too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 11:59:47 -04:00
benbrownandClaude Fable 5 477c5472dd skill: make the peltier skill consumable across agent harnesses
The SKILL.md Agent Skills standard (agentskills.io) is now read natively by
Codex, Copilot, VS Code, Cursor, Gemini CLI, opencode, Goose, Amp, Zed,
Factory, and ZeroClaw — so the portable move is not per-harness adapter
files (forked content that drifts) but one canonical skill placed where
each harness actually looks.

- Spec-compliant frontmatter: license, compatibility (the Linux-only
  measurement story, stated up front), version/author/tags top-level
  (ZeroClaw's runtime reads those; the spec ignores unknown fields).
  reference/ renamed to references/ per the spec's conventional layout.
- .agents/skills/peltier/ mirror: the cross-tool convergence path (Codex,
  Zed, Cursor, Gemini CLI, Copilot, opencode, Goose, Amp). Byte-identical
  to the .claude canonical, enforced by CI — drift between the two copies
  is a red build, not a footnote.
- AGENTS.md at the repo root for the ~20 harnesses that read it (Claude
  Code does not; CLAUDE.md remains its file). Deliberately thin: it points
  at CLAUDE.md and the skill instead of restating rules.
- scripts/install-skill.sh: stamps a consumer repo at both discovery paths
  (--layout claude|agents|both), or emits a script-less --zeroclaw-variant.
  ZeroClaw's skill security policy blocks script files by default
  (skills.allow_scripts off) — its audit rejected the full skill and passes
  the variant, verified against the real zeroclaw binary. The variant loses
  nothing: preflight.sh still exists exactly once, in the peltier checkout
  the skill already requires, and SKILL.md now documents running it from
  there. Re-implementing preflight inline is named as a refusal condition.
- CI (skill-preflight): frontmatter upgraded to a full Agent Skills spec
  conformance check on BOTH copies (name rules, dir match, description and
  body limits, metadata string-map), plus mirror equality and a functional
  installer test (both layouts identical to canonical, variant carries no
  scripts/, nonexistent target refused).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 11:59:26 -04:00
benbrownandGitHub ec73e277f1 Merge pull request #18 from bdbrown4/fix/skill-frontmatter
skill: fix unloadable SKILL.md frontmatter, and test it in CI
2026-07-14 14:10:42 -04:00
benbrownandClaude Opus 4.8 db5caf0b5d skill: fix unloadable SKILL.md frontmatter, and test it in CI
The description was an unquoted YAML scalar containing "trust layer:
equivalence" — a colon-space inside a plain scalar makes YAML parse it as a
nested mapping, so the frontmatter raised "mapping values are not allowed in
this context" and the skill would not load at all.

Quoted the scalar and replaced the colon with an em dash.

The real defect is that CI asserted the preflight script's behavior but never
checked that the skill it ships is loadable. Added a step that parses the
frontmatter, requires name/description to be non-empty strings, and requires
name to match the directory — so an unloadable skill fails the build instead
of failing the user.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:59:59 -04:00
benbrownandGitHub 85eaf43dfe Merge pull request #17 from bdbrown4/audit/resolve-findings
gates: close the audit findings — enforce the gates the docs claimed
2026-07-14 13:45:47 -04:00
benbrownandClaude Opus 4.8 af3fc3dccd skill: expose the trust layer as a consumable peltier skill
The reusable artifact here was never the vendored targets — it is the
discipline: prove equivalence, prove significance, or claim nothing. This
packages it as a Claude Code skill usable from any repo.

Two modes. `verify` works anywhere, on any two shell commands in any
language: equivalence before timing -> A/A calibration -> interleaved A/B
with a bootstrap CI -> a verdict decided by the CI lower bound, never the
median. `attempt` drives the full in-repo loop (gates, pristine-baseline
verdict, ledger row, ROI report).

It drives the real bench-runner binary and refuses rather than degrade: on
an unsupported host, or with no trust layer reachable, preflight stops and
says so instead of falling back to a hand-rolled timing loop. A second copy
of the statistics is a second thing that can lie. A refusal ends the claim,
not the work.

An adversarial review of the skill caught six high-severity defects, all
fixed here — several of them the very errors the skill exists to prevent:

- verify mode had no risk classification at all. bench-runner emits only
  accepted/rejected-bench; needs-human-review is minted by the in-repo
  verdict path, which verify does not run. A concurrency change with
  byte-identical output would have sailed through as "accepted". The skill
  now makes the agent the classifier and says so explicitly.
- the accept template exposed `pin_prefix`, which is inert for
  compare/aa/calibrate (only `verdict` reads it) — an agent would have set
  it and reported pinning that never happened. Now documents wrapping both
  sides in taskset instead.
- the equivalence gate compared stdout only, so two commands that write to
  stderr and a dist/ tree would "GOLDEN PASS" on two empty files. Now hashes
  stdout + stderr + exit code + artifact tree, and an empty diff over empty
  output is a failed gate, not a passed one.
- nothing told the agent to build two coexisting immutable artifacts, so a
  `cargo run` baseline could rebuild from the patched tree mid-bench — the
  exact trap phase1-verdict-smoke-001 recorded.
- service mode was documented as generic HTTP. It is not: the server must
  take <port> <doc> <iters>, print READY, and close the connection. A stock
  Express app hangs the harness forever. Contract now stated.
- the CI refusal test could not pass: preflight also walks up from its own
  location, so running it in-place found this very repo. The test now copies
  the skill out of the tree first.

CI job `skill-preflight` asserts the contract that matters — resolve when a
trust layer is reachable, REFUSE when it is not, and work when consumed from
another repo via PELTIER_HOME. It deliberately does not assert a statistical
outcome: a shared runner is too noisy for that, which is precisely why the
skill calibrates before it claims.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:39:38 -04:00
benbrownandClaude Opus 4.8 899d55f4b6 gates: close the audit findings — enforce the gates the docs claimed
An adversarial audit found the enforcement story ahead of the code: gates
that were documented as hard gates were advisory, manual, or absent, and
several human-facing claims outran the machine record. This makes the
claims true.

High findings

- Differential fuzz was documentation, not enforcement: verdict hardcoded
  fuzz_iters=0 and diff-test hardcoded the gate to Skipped, while the case
  studies claimed 10k-iteration fuzz on the same wins. Fuzz is now a real
  pipeline gate (strict FUZZ-RESULT contract, executed count recorded), and
  it is inherently baseline-vs-candidate, so it runs on the accept path and
  reports Skipped in the standalone `just gates` flow. New hard rule: a
  machine `accepted` verdict is impossible unless the fuzz gate actually
  passed — otherwise it caps at needs-human-review.
- The agent's system prompt claimed FP/concurrency/unsafe patches were
  "routed to human review automatically". No such mechanism existed. Added
  a conservative lexical risk classifier (crates/verdict/src/risk.rs) that
  forces needs-human-review on any would-be accept carrying those signals;
  fp-tolerance equivalence always signals.
- The local verdict path ran agent-influenced code unsandboxed. It now runs
  under scripts/no-net.sh (network namespace) and fails closed. Upstream
  test suites are hash-verified against corpora/<t>/TESTSUITE.sha256 when
  present (scripts/pin-testsuite.sh generates them).

Also fixed, found while fixing the above

- The pipeline script's `set -e` was inert (brace group as the left operand
  of `&&`), so a failing candidate build did not abort the run and verdict
  could bench a stale binary. Now a scoped subshell whose status is branched
  on at top level.
- A wrapper that exits before exec'ing (no-net.sh refusing, bad wrapper path)
  stranded RUNNING.lock and left read_verdict polling forever. Failure
  accounting now lives outside the wrapper.
- harnessd's patch allowlist ignored git rename/copy headers and --no-prefix
  diffs; the rename-escape case is now a committed regression test.
- The workspace did not compile on Windows (ungated Unix APIs). cfg-gated;
  71 portable tests now run on both platforms.
- pin-check regenerated the corpus manifest instead of verifying it; it is
  now verify-only, with a deliberate `just pin-corpus` to re-pin.
- Max RSS is captured per run on Unix; PMU counters are opt-in diagnostics
  (compare --perf-stat), never part of the accept decision.

Docs now match the code, including what is NOT yet enforced: no target ships
a TESTSUITE.sha256 pin, no target declares [build].tsan, and matmul is not
wired to the fp-tolerance gate — each is stated as mechanized-but-inert
rather than done. Corrected the stale "33 ledger rows" (34), the playbook's
class-3 cJSON win (rejected), adversarial-review.md's sanitizer-separation
claim (five accepted rows carry sanitizers_clean=false), the unsupported
"40,000 requests" figure, and the blanket "historical rows record
fuzz_iters=0" (8 of 10; phase0-tokei-002/-003 record 4,332).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:10:14 -04:00
benbrownandGitHub 21352efe6c Correct project name in README.md
Update project name from 'Peltier' to 'peltier.io' in README.
2026-07-12 14:19:24 -04:00
benbrownandGitHub 1fbead809c Merge pull request #16 from bdbrown4/copilot/configure-github-pages-deployment
docs: wire up configure-pages in GitHub Pages workflow
2026-07-12 14:17:11 -04:00
benbrownandGitHub e55ac2b9c7 Merge pull request #15 from bdbrown4/claude/test-wsk42i 2026-07-12 13:35:47 -04:00
benbrownandGitHub 94b3ab9154 Merge pull request #14 from bdbrown4/claude/test-wsk42i
Phase 5 research forks + adversarial review, mimalloc ruling, and docs site
2026-07-11 20:41:05 -04:00
benbrownandGitHub d1ef2a0dd6 Merge pull request #13 from bdbrown4/claude/test-wsk42i
Phase 4 complete: service latency bench, real service win under replay, mechanical ROI reports
2026-07-11 20:00:51 -04:00
benbrownandGitHub 3951857cf2 Merge pull request #12 from bdbrown4/claude/test-wsk42i 2026-07-11 19:12:09 -04:00
benbrownandGitHub 7f67c3bb02 Merge pull request #11 from bdbrown4/claude/test-wsk42i
Phase 2 complete: unattended agent loop, OS isolation, 20 audited attempts, 3 verified wins
2026-07-11 13:57:47 -04:00
benbrownandGitHub 2386151ddb Merge pull request #10 from bdbrown4/claude/test-wsk42i 2026-07-10 08:25:39 -04:00
benbrownandGitHub 4eef6a7bd4 Merge pull request #9 from bdbrown4/claude/test-wsk42i 2026-07-09 19:38:59 -04:00
benbrownandGitHub 5be5cad0d3 Merge pull request #8 from bdbrown4/claude/test-wsk42i 2026-07-09 18:39:47 -04:00
benbrownandGitHub 01ac70034c Merge pull request #7 from bdbrown4/claude/test-wsk42i 2026-07-06 20:22:53 -04:00
benbrownandGitHub d7a83c1b3c Merge pull request #6 from bdbrown4/claude/test-wsk42i 2026-07-06 20:08:20 -04:00
benbrownandGitHub eb32fc24c0 Merge pull request #5 from bdbrown4/claude/test-wsk42i 2026-07-06 19:53:31 -04:00
benbrownandGitHub 5209d8e633 Merge pull request #4 from bdbrown4/claude/test-wsk42i 2026-07-06 19:40:43 -04:00
benbrownandGitHub 7cd9db4971 Merge pull request #3 from bdbrown4/claude/test-wsk42i 2026-07-06 19:09:09 -04:00
benbrownandGitHub e69d2c46ed Merge pull request #2 from bdbrown4/claude/test-wsk42i 2026-07-06 16:04:24 -04:00
benbrownandGitHub 1ef2bb4fdb Merge pull request #1 from bdbrown4/claude/test-wsk42i 2026-07-06 14:48:02 -04:00
benbrownandGitHub 836d4c9208 Initial commit 2026-07-06 14:20:25 -04:00