-
Notifications
You must be signed in to change notification settings - Fork 0
Release notes
Eugene Lazutkin edited this page Aug 21, 2026
·
4 revisions
A footgun the first external consumer found within hours of 0.1.0, fixed additively.
-
parseSidecar(text).version— the format version as a number.0.1.0exportedSIDECAR_VERSIONas the number1whilereadFrontmatterreturned every frontmatter value as a string, sofm.sidecar === SIDECAR_VERSION— the comparison the package's own two exports invite — wasfalsefor every valid sidecar, and a consumer reading it that way saw a valid file as unversioned. Nothing was broken internally (sidecarProblemscoerces before comparing) andparse.d.tsalready declaredRecord<string, string>honestly; the defect was the pair of exports, which no single-file check can see. The fix is purely additive: a typedversionrides on the objectparseSidecarreturns,readFrontmatterstays a generic reader that knows nothing about any key's semantics, and the publishedfrontmatter: Record<string, string>contract is untouched — so nothing written against0.1.0changes meaning. Coercing insidereadFrontmatterwas considered and rejected: a reader that knows one key's semantics is a reader that will eventually be asked to know a second, and the argument for the second is always the first one. Reported by the nano-binary-search project. -
npm page links:
repository,homepage, andbugswere absent frompackage.jsonsince the first publish, so the npm page had no link back to the source and provenance had nothing to attest against. Added. - Internal: the
mutating-predicatehazard lifted into the bundledsorted-array familyartifact, which now covers every claim in nano-binary-search's publishedINVARIANTS.md. Tests run on Node, Bun, and Deno; CI is 3 OS × Node 22/24/26.
The §6.6 sidecar format: a file now has to say it is a sidecar, and a consumer can find one without being told where it lives.
-
Frontmatter is the discriminator:
sidecar(integer format version, exported asSIDECAR_VERSION),package(must equal the host package's name, which catches a vendored copy) andbinds(the versions the claims are asserted for) are required;exportandverified: cistay optional.INVARIANTS.mdis a common filename for things that are not sidecars — human prose recording "properties that must hold", agent guardrails at.claude/INVARIANTS.md— and reading either as a contract would promote somebody's sentences to axioms.isSidecar(text)answers "is this one at all" without throwing, because the common case is a file a consumer should skip in silence;readFrontmatterandsidecarProblemsexpose the reasons for logging, andparseSidecarnow fails with a located error naming every missing key. -
Sidecar discovery:
resolveSidecar(read)(subpathinvariants-sidecar/resolve.js) resolves an installed package's sidecar — the manifest'sinvariantskey first, since there the author states the file is a sidecar, then a rootINVARIANTS.md, provisional until its frontmatter validates. It takes a reader over the package directory instead of importingnode:fs, so the module stays as runtime-agnostic as the rest ofsrc/and the zero-dependency shape survives discovery.nullmeans the package has no sidecar and{path, skipped}means one existed and was refused, with the reason, so a consumer can tell those two apart. The bundledsatisfies(version, range)covers the exact,^,~and*formsbindsactually uses and returnsnullfor anything else — unknown rather than false, because guessing at a range it does not implement would silently downgrade a live sidecar to stale. -
Oracle ingestion gated on
verified: ci:oracleInputsFromSidecaryields axioms only from a sidecar the package's own CI keeps true, returning{axioms: [], declares: [], unverified: true}otherwise — empty and marked rather than thrown, so a caller sweeping many packages needs notry/catch. Pass{allowUnverified: true}to read the proposals anyway. An unverified sidecar is a proposal, not provenance. -
Parser hardened against ReDoS: two rounds of
js/polynomial-redosfindings inparse.jswere fixed rather than dismissed, becauseparseSidecaris the advertised safe-on-untrusted-input step — tools read sidecars straight out ofnode_modules. The surviving$-anchored pump inCLAIM_REmeasured 5.8 s on a 160 KB adversarial line and was rewritten to a single-quantifier head pluslastIndexOf, verified differentially against the old regex over a structured corpus and 200k fuzzed lines before it landed; the same line now parses in 1.0 ms. Pre-splitting input on\nis not a defence here, which is the calibration worth keeping: JS.also excludes\r, so a lone carriage return still fails the$anchor and arms the rescan. The restructure delivered a real diagnostic in passing — a claim head that does not close with:is now named.
Internal: tape-six 1.16.4, prettier 3.9.6. Tests run on Node, Bun, and Deno; CI is 3 OS × Node 22/24/26.
The initial release — the experiment's static-land core, end to end:
-
Dictionary completer:
complete()derives every missing derivable method to fixpoint from the static-land derivation lattice (DERIVATIONS), reports provenance, and lists the consistency obligations of hand-provided derivable methods. -
Law/consistency property-test generator:
LAWSrecords for Setoid, Semigroup, Monoid, Functor, Applicative, Chain, and Monad;makeLawTests/makeConsistencyTestsproducet.prop()-ready tests — consistency checks every applicable derivation path, since the paths that avoid a corrupted method are what refute it;runLawsdrives them through tape-six-fast-check. -
Sidecar parser and check compiler:
parseSidecarreads the moonshot §6.5 artifact format into inert data (it never evaluates);compileCheck/compileChecksare the explicit trust step;lawTestsFromSidecarbridges a Laws section to the law suite. The worked binary-search artifact is verified end-to-end against the real published nano-binary-search, including the complexity bound via an instrumented comparator and a deterministic hazard witness. -
Call-site guards:
guardsFromSidecar(subpathinvariants-sidecar/guards.js) turns check-bearingpre:claims into tape-six-invariant guards — counted assertions when a tape-six run exercises the call site, the configured absent behavior otherwise. -
Oracle bridge:
oracleInputsFromSidecar/instantiateAxioms/declareFromSidecaremitapodictumwire shapes from blessedlaw:/effects:claims; the oracle is not a dependency — the integration tests load it dynamically (installed package first, fleet sibling second) and skip cleanly without it.
A drafted family sidecar for nano-binary-search's ten sibling exports ships in the repo (sidecars/), all claims surviving refutation. Tests run on Node, Bun, and Deno; CI is 3 OS × Node 22/24/26.