// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts® // Store rules: what unit-state stores as reusable, reads per round, the // reads a unit needs, salvage by environment, the environment on the store // side, resume by environment, the migrations preflight and the instrument // preflight. A Run is built part by part. #include import std; import Crafter.Review; namespace fs = std::filesystem; using namespace Crafter::Review; namespace { std::int32_t Failures = 0; const std::string Fn(Plan::FunctionalLens); void Check(std::string_view name, bool cond, std::string_view detail = {}) { std::println("{}{}{}", cond ? " ok " : " FAIL ", name, !cond && !detail.empty() ? std::format(" ({})", detail) : std::string()); if (!cond) ++Failures; } void Write(const fs::path& path, std::string_view text) { fs::create_directories(path.parent_path()); std::ofstream(path, std::ios::binary) << text; } std::set Keys(const Json& object) { std::set keys; for (auto it = object.begin(); it != object.end(); ++it) keys.insert(it.key()); return keys; } Json Defaults() { Json out = Json::object(); for (const Plan::Lens& l : Plan::Lenses) out[std::string(l.file)] = std::string(l.env); return out; } std::string Git(const fs::path& repo, std::vector args) { std::vector argv = {"git", "-C", repo.string(), "-c", "user.email=t@t", "-c", "user.name=t"}; std::ranges::move(args, std::back_inserter(argv)); const Process::Captured run = Process::Run(argv); if (run.returnCode != 0) throw std::runtime_error(std::format("{}: {}", Dyn::Join(argv, " "), run.err)); return Dyn::Strip(run.out); } } int main() { std::println("unit-state: what is stored as reusable; reads per round; reads needed per lens"); Platform::SetMode(Platform::Mode::Native); // No git of this test reads a global config. setenv("GIT_CONFIG_GLOBAL", "/dev/null", 1); setenv("GIT_CONFIG_SYSTEM", "/dev/null", 1); const fs::path td = fs::temp_directory_path() / std::format("crafter-review-store-rules-{}", Platform::PublishedPid()); fs::remove_all(td); fs::create_directories(td); auto noLog = [](const std::string&) {}; auto stored = [&](std::vector recs, const Json& parts, const Json& coverage, const Json& findings, const Json& before = Json::object(), std::int64_t rnd = 1, bool twice = false) { Run::Run r; r.records = std::move(recs); r.hash = "H"; r.h8 = "H"; r.round = rnd; r.dumpPath = td / std::format("run-{}.json", rnd); r.repo = td; r.results = {{{"lens", "L"}, {"coverage", coverage}, {"findings", findings}, {"notes", Json::array()}, {"parts", parts}}}; r.state = {{"version", 1}, {"entries", before}, {"personaPass", nullptr}}; r.statePath = td / "unit-state.json"; r.a.date = "2026-10-15"; r.log = noLog; // The file is the record the store merges into (2026-10-31). State::SaveWhole(r.statePath, r.state); r.StoreState(); if (twice) r.StoreState(); return r.state.at("entries"); }; auto rec = [](const std::string& u, const std::string& k) { return Json {{"label", std::format("L:block:{}", u)}, {"lens", "L"}, {"lensFile", "repo-bug-prover.md"}, {"unit", u}, {"kind", "block"}, {"status", "ok"}, {"reuseKey", k}}; }; auto part = [](const std::string& u, const std::string& v) { return Json {{"label", std::format("L:block:{}", u)}, {"kind", "block"}, {"unit", u}, {"verdict", v}, {"findings", v != "SEND-READY" ? 1 : 0}}; }; auto cov = [](const std::string& u, const std::string& v) { return Json {{"item", u}, {"verdict", v}, {"basis", ""}}; }; auto finding = [](const std::string& item, bool discharged, const std::optional& by = std::nullopt) { Json f = {{"finding", "f"}, {"items", Json::array({item})}, {"discharged", discharged}}; if (by) f["dischargedBy"] = *by; return f; }; Json e = stored({rec("X", "kx"), rec("Y", "ky")}, Json::array({part("X", "SEND-READY"), part("Y", "SEND-READY")}), Json::array({cov("X", "clear"), cov("Y", "clear")}), Json::array()); Check("two clean passes -> both stored", Keys(e) == std::set{"kx", "ky"} && e.at("kx").at("unit") == "X"); e = stored({rec("X", "kx"), rec("Y", "ky")}, Json::array({part("X", "FIX FIRST"), part("Y", "SEND-READY")}), Json::array({cov("X", "clear"), cov("Y", "clear")}), Json::array({finding("Y", false)}), {{"kx", {{"unit", "X"}}}}); Check("the pass on X returns a finding that cites only Y -> neither stored, X loses its earlier entry", e.empty(), e.dump()); e = stored({rec("X", "kx"), rec("Y", "ky")}, Json::array({part("X", "SEND-READY"), part("Y", "SEND-READY")}), Json::array({cov("X", "defect"), cov("Y", "clear")}), Json::array({finding("X", true, "w")})); Check("a defect verdict whose only citing finding is discharged -> stored", Keys(e) == std::set{"kx", "ky"} && e.at("kx").at("coverage").at("verdict") == "defect"); e = stored({rec("X", "kx"), rec("Y", "ky")}, Json::array({part("X", "SEND-READY"), part("Y", "SEND-READY")}), Json::array({cov("X", "defect"), cov("Y", "clear")}), Json::array()); Check("a defect verdict with no citing finding -> not stored", Keys(e) == std::set{"ky"}); e = stored({rec("p3:absent", "k"), rec("p4:absent", "k")}, Json::array({part("p3:absent", "SEND-READY"), part("p4:absent", "FIX FIRST")}), Json::array({cov("p3:absent", "clear"), cov("p4:absent", "defect")}), Json::array({finding("p4:absent", false)}), {{"k", {{"unit", "p3:absent"}}}, {"other", {{"unit", "Z"}}}}); Check("two units under one key, one defective -> the key is not stored and its earlier entry is dropped", Dyn::Equal(e, {{"other", {{"unit", "Z"}}}}), e.dump()); e = stored({rec("p3:x#hdr", "k"), rec("p8:x#hdr", "k")}, Json::array({part("p3:x#hdr", "SEND-READY"), part("p8:x#hdr", "SEND-READY")}), Json::array({cov("p3:x#hdr", "clear"), cov("p8:x#hdr", "n/a")}), Json::array()); Check("two units under one key, both clean -> stored once", Keys(e) == std::set{"k"}); const Json oneRead = Json::array({{{"hash", "H"}, {"round", 1}, {"run", "run-1.json"}}}); const Json e1 = stored({rec("X", "kx")}, Json::array({part("X", "SEND-READY")}), Json::array({cov("X", "clear")}), Json::array(), Json::object(), 1, true); Check("reads: a clean pass is one read however often the run stores it", Plan::ReadsOf(e1.at("kx")) == 1 && Dyn::Equal(e1.at("kx").at("reads"), oneRead) && Plan::ReadIn(e1.at("kx"), "H", 1) && !Plan::ReadIn(e1.at("kx"), "H", 2)); const Json e2 = stored({rec("X", "kx")}, Json::array({part("X", "SEND-READY")}), Json::array({cov("X", "clear")}), Json::array(), e1, 2); Check("reads: the next round on the same hash is the second read; a relaunch of the same round adds nothing", Plan::ReadsOf(e2.at("kx")) == 2 && Plan::ReadsOf(stored({rec("X", "kx")}, Json::array({part("X", "SEND-READY")}), Json::array({cov("X", "clear")}), Json::array(), e1).at("kx")) == 1); const Json e3 = stored({rec("X", "kx")}, Json::array({part("X", "FIX FIRST")}), Json::array({cov("X", "defect")}), Json::array({finding("X", false)}), e2, 3); Check("reads: a finding on the third read drops the count to nothing", !e3.contains("kx")); auto need = [](const std::string& lf, const std::string& kind = "block", const Json& unitKind = "code", std::int64_t x = 3) { Run::Run r; r.x = x; return r.ReadsNeeded({{"lensFile", lf}, {"kind", kind}, {"unitKind", unitKind}}); }; Check("reads needed: 3 for a static code unit, 1 for a functional unit, a whole pass, and everything at --reads 1", need("repo-bug-prover.md") == 3 && need("repo-better-solution.md") == 3 && need(Fn) == 1 && need("repo-better-solution.md", "whole", nullptr) == 1 && need("repo-bug-prover.md", "block", "code", 1) == 1 && Plan::Reads == 3); // Salvage: an earlier run's output is evidence only if its environment // was there (exercised), whatever classify says. { Run::Run r; const fs::path sd = td / "old-run"; fs::create_directories(sd / "out"); r.salvageDirs = {sd}; r.testMode = false; r.x = 1; r.repo = td; r.environments = {{Fn, "browser"}, {"repo-bug-prover.md", "none"}}; r.log = noLog; r.a.dryRun = false; r.a.noSalvage = false; const std::string res = R"({"type":"result","subtype":"success","is_error":false,"structured_output":{"verdict":"SEND-READY","findings":[],"notes":[],"coverage":[]},"usage":{"input_tokens":1,"output_tokens":1}})"; const std::string initNo = R"({"type":"system","subtype":"init","model":"m","mcp_servers":[],"tools":["Read"]})"; const std::string initOk = R"({"type":"system","subtype":"init","model":"m","mcp_servers":[{"name":"playwright","status":"connected"}],"tools":["mcp__playwright__browser_snapshot"]})"; const std::string call = R"({"type":"assistant","message":{"role":"assistant","content":[{"type":"tool_use","id":"t1","name":"mcp__playwright__browser_snapshot","input":{}}]}})" "\n" R"({"type":"user","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"t1","content":"- page"}]}})"; const Json job = {{"label", "repo-functional:whole"}, {"lensFile", Fn}, {"kind", "whole"}, {"model", "m"}}; Write(sd / "out" / "repo-functional:whole.jsonl", std::format("{}\n{}\n", initNo, res)); Check("salvage: a functional whole pass whose server never connected is not salvaged (no browser = no evidence, salvaged or not)", !r.Salvage(job)); Write(sd / "out" / "repo-functional:whole.jsonl", std::format("{}\n{}\n{}\n", initOk, call, res)); std::optional> got = r.Salvage(job); Check("...with the server connected and a browser call it is, with its environment on the record", got && got->first.at("environment") == "browser" && Dyn::Truthy(got->first.at("salvaged")) && got->second.at("verdict") == "SEND-READY"); Write(sd / "out" / "repo-bug-prover:block:X.jsonl", std::format("{}\n{}\n", initNo, res)); const Json bj = {{"label", "repo-bug-prover:block:X"}, {"lensFile", "repo-bug-prover.md"}, {"kind", "block"}, {"model", "m"}}; got = r.Salvage(bj); Check("a static pass (environment none) is salvaged as classified", got && got->first.at("environment") == "none"); // Across environments: the scratch dir's marker says what its passes // had; no marker = the defaults. r.environments = {{Fn, "browser"}, {"repo-bug-prover.md", "supabase"}}; const bool unmarked = r.Salvage(bj).has_value(); Write(sd / "environments", R"({"repo-bug-prover": "supabase"})"); r.envMarkers.clear(); const std::optional> marked = r.Salvage(bj); r.environments = {{Fn, "browser"}, {"repo-bug-prover.md", "none"}}; const bool back = r.Salvage(bj).has_value(); Check("salvage: an output is reused only in the environment its scratch dir's marker names (a dir without one ran the defaults)", !unmarked && marked && marked->first.at("environment") == "supabase" && !back); } // The environment on the STORE side. const fs::path fx = fs::current_path() / "tests" / "Goldens" / "fixture" / "commits"; const Inventory::Built built = Inventory::Build("commits", fx.string()); Run::Run g; g.a.artifact = fx.string(); g.a.dryRun = false; g.a.date = "2026-10-22"; g.units = built.out.at("units"); g.lines = built.lines; for (const Plan::Lens& l : Plan::Lenses) g.charterSha[std::string(l.file)] = "c"; g.state = State::EmptyState(); g.x = 1; g.h8 = "H"; g.round = 1; g.hash = "H"; g.repo = td; g.statePath = td / "us-env.json"; g.dumpPath = td / "run-env.json"; g.log = noLog; const std::string U = "p2:hello.py#1"; auto unitJob = [&] { for (Json j : Plan::PlanLens("repo-bug-prover.md", g.units, g.lines).blocks) { if (j.at("unit") == U) { j["gate"] = "G"; return j; } } throw std::runtime_error("no unit job"); }; // One round of the bug-prover on U in env: PrepareBlocks (reuse or a // job), then - if it ran - a pass with that verdict, stored. auto round = [&](const std::string& env, const std::string& verdict) -> std::pair { g.environments = Defaults(); g.environments["repo-bug-prover.md"] = env; g.records.clear(); g.results.clear(); g.wholeParts.clear(); std::map> parts = {{"repo-bug-prover", {}}}; const std::vector jobs = g.PrepareBlocks("repo-bug-prover", {unitJob()}, parts); if (jobs.empty()) return {"reused", nullptr}; const Json& j = jobs.front(); g.records = {{{"label", j.at("label")}, {"lens", "repo-bug-prover"}, {"lensFile", "repo-bug-prover.md"}, {"unit", U}, {"kind", "block"}, {"status", "ok"}, {"reuseKey", j.at("reuseKey")}, {"otherKeys", j.at("otherKeys")}}}; const bool bad = verdict != "SEND-READY"; g.results = {{{"lens", "repo-bug-prover"}, {"coverage", Json::array({{{"item", U}, {"verdict", bad ? "defect" : "clear"}, {"basis", ""}}})}, {"notes", Json::array()}, {"findings", bad ? Json::array({finding(U, false)}) : Json::array()}, {"parts", Json::array({{{"label", j.at("label")}, {"verdict", verdict}}})}}}; g.StoreState(); return {"ran", j}; }; auto inEntries = [&](const Json& key) { return g.state.at("entries").contains(key.get()); }; const auto [s1, j1] = round("none", "SEND-READY"); const auto [s2, j2] = round("supabase", "SEND-READY"); Check("store: a clean verdict bought in one environment is not reused in another (none -> supabase runs the unit again); each is stored under its own key", s1 == "ran" && s2 == "ran" && j1.at("reuseKey") != j2.at("reuseKey") && inEntries(j1.at("reuseKey")) && inEntries(j2.at("reuseKey")) && std::ranges::contains(j2.at("otherKeys"), j1.at("reuseKey"))); Check("...and in its own environment it is reused", round("none", "SEND-READY").first == "reused" && round("supabase", "SEND-READY").first == "reused"); g.state["entries"].erase(j2.at("reuseKey").get()); const auto [s3, j3] = round("supabase", "FIX FIRST"); Check("store: two environments, one unit, different verdicts - the supabase pass finds a defect the none pass read clean: neither verdict survives, so switching the lens back to none re-reads the unit", s3 == "ran" && !inEntries(j1.at("reuseKey")) && !inEntries(j3.at("reuseKey")) && round("none", "SEND-READY").first == "ran"); // The whole pass: its key carries the environment, and a whole pass that // is not clean drops the other environments' whole verdicts. Json wj = Plan::PlanLens("repo-better-solution.md", g.units, g.lines).whole; wj["gate"] = "G"; g.environments = Defaults(); g.records.clear(); g.ReuseWhole("repo-better-solution", wj); const std::string kwNone = wj.at("reuseKey").get(); g.state["entries"][kwNone] = {{"lens", "repo-better-solution.md"}, {"unit", nullptr}, {"kind", "whole"}, {"hash", "H"}, {"run", "r"}, {"coverage", Json::array({{{"item", "whole:order"}, {"verdict", "clear"}, {"basis", ""}}, {{"item", "whole:absent"}, {"verdict", "clear"}, {"basis", ""}}})}, {"findings", Json::array()}, {"notes", Json::array()}, {"summary", "s"}}; Json copy = wj; const bool reusedNone = g.ReuseWhole("repo-better-solution", copy).has_value(); g.environments["repo-better-solution.md"] = "supabase"; Json ws = wj; const bool reusedSup = g.ReuseWhole("repo-better-solution", ws).has_value(); g.records = {{{"label", ws.at("label")}, {"lens", "repo-better-solution"}, {"lensFile", "repo-better-solution.md"}, {"unit", nullptr}, {"kind", "whole"}, {"status", "ok"}, {"reuseKey", ws.at("reuseKey")}, {"otherKeys", ws.at("otherKeys")}}}; g.results = {{{"lens", "repo-better-solution"}, {"coverage", Json::array()}, {"findings", Json::array({finding("whole:order", false)})}, {"notes", Json::array()}, {"parts", Json::array()}}}; g.wholeParts = {{"repo-better-solution", {{"verdict", "FIX FIRST"}, {"coverageMissing", Json::array()}, {"status", "ok"}}}}; g.StoreState(); Check("store: the whole pass - a clean whole verdict is reused in its environment and not in another; a whole pass that is not clean in supabase drops the clean one none held", reusedNone && !reusedSup && ws.at("reuseKey") != kwNone && std::ranges::contains(ws.at("otherKeys"), Json(kwNone)) && !g.state.at("entries").contains(kwNone)); // Resume across environments: the checkpoint's `environments` (none in a // checkpoint written before 2026-10-16.1 = the defaults). g.resume = {{"run", "r1"}, {"results", Json::array({{{"lens", "repo-bug-prover"}, {"verdict", "SEND-READY"}, {"findings", Json::array()}, {"coverageMissing", Json::array()}, {"parts", Json::array()}}})}, {"environments", {{"repo-bug-prover", "supabase"}}}}; g.newRound = false; g.records.clear(); g.environments = Defaults(); const bool no = g.Resumable("repo-bug-prover", "repo-bug-prover.md", "G").has_value(); g.environments["repo-bug-prover.md"] = "supabase"; const std::optional yes = g.Resumable("repo-bug-prover", "repo-bug-prover.md", "G"); g.resume.erase("environments"); const bool old = g.Resumable("repo-bug-prover", "repo-bug-prover.md", "G").has_value(); g.environments["repo-bug-prover.md"] = "none"; const bool oldDefault = g.Resumable("repo-bug-prover", "repo-bug-prover.md", "G").has_value(); Check("resume: a lens result is resumed only in the environment it was bought in (an old checkpoint without environments = the defaults)", !no && yes && yes->at("verdict") == "SEND-READY" && !old && oldDefault); // The preflight of a gate with the database under test. const fs::path repo = td / "mig"; fs::create_directories(repo / "supabase" / "migrations"); for (const std::string_view f : {"20261001000000_a.sql", "20261002000000_b.sql"}) Write(repo / "supabase" / "migrations" / f, "select 1;\n"); Write(repo / "supabase" / "migrations" / "README", "not a migration\n"); Git(repo, {"init", "-q"}); Git(repo, {"add", "."}); Git(repo, {"commit", "-qm", "base"}); const std::string mbase = Git(repo, {"rev-parse", "HEAD"}); Write(repo / "supabase" / "migrations" / "20261002000000_b.sql", "-- b, now with a filter\nselect 2 where true;\n"); Git(repo, {"commit", "-qam", "the range changes b"}); g.trees = {repo.string()}; g.a.base = mbase; // What the CLI records: the statements, its own spacing, no comment. const std::string appliedA = "select 1"; const std::string appliedB = "select 2 where true"; using Rows = std::vector>>; auto rows = [](Rows r) { return [r](std::string_view, std::string_view) { return Run::QueryResult({"version", "s"}, r); }; }; g.query = rows({{"20261001000000", appliedA}, {"20261002000000", appliedB}}); const auto same = g.MigrationsDrift("u"); g.query = rows({{"20261001000000", appliedA}}); const auto behind = g.MigrationsDrift("u"); g.query = rows({{"20261001000000", appliedA}, {"20261002000000", appliedB}, {"20260901000000", "x"}}); const auto ahead = g.MigrationsDrift("u"); g.query = rows({{"20261001000000", "select 1 -- other text, a base migration: versions alone"}, {"20261002000000", "select 1"}}); const auto stale = g.MigrationsDrift("u"); g.query = [](std::string_view, std::string_view sql) -> Run::QueryResult { if (sql.contains("statements")) throw PgWire::SqlError({{'C', "42703"}, {'M', "column \"statements\" does not exist"}}); return {{"version", "s"}, {{"20261001000000", std::nullopt}, {"20261002000000", std::nullopt}}}; }; const auto oldCli = g.MigrationsDrift("u"); g.query = [](std::string_view, std::string_view) -> Run::QueryResult { throw PgWire::SqlError({{'C', "42P01"}, {'M', "relation \"supabase_migrations.schema_migrations\" does not exist"}}); }; const auto plain = g.MigrationsDrift("u"); auto has = [](const std::optional& text, std::string_view part) { return text && text->contains(part); }; Check("preflight: the database's applied migrations must be the range HEAD's - one not applied, one applied that HEAD lacks, or a migration of the range applied with other content (amended, the stack not reset) is evidence drift", !same.first && has(same.second, "2 applied migrations") && has(same.second, "1 of the range compared by content") && has(behind.first, "at HEAD, not applied: 20261002000000") && has(ahead.first, "applied, not at HEAD: 20260901000000") && has(stale.first, "applied with other content than HEAD has: 20261002000000") && !has(stale.first, "20261001000000"), std::format("{} | {} | {} | {}", same.second.value_or("-"), behind.first.value_or("-"), ahead.first.value_or("-"), stale.first.value_or("-"))); Check("preflight: the content is compared blind to comments, whitespace and semicolons; an old CLI without the statements column compares versions; a database without the table is a note", PgWire::Fingerprint("-- b, now with a filter\nselect 2 where true;\n") == PgWire::Fingerprint("select 2 where true") && PgWire::Fingerprint("select 2 where true") != PgWire::Fingerprint("select 2 where false") && PgWire::Fingerprint("select '--not a comment'") != PgWire::Fingerprint("select") && !oldCli.first && !plain.first && has(plain.second, "not compared")); g.trees = {td.string()}; Check("preflight: a tree without supabase/migrations/ at HEAD compares nothing", !g.MigrationsDrift("u").first); g.query = [](std::string_view url, std::string_view sql) { return PgWire::Query(url, sql); }; g.cfg = {{"supabase", {{"dbUrl", "postgresql://postgres:postgres@127.0.0.1:1/postgres"}, {"start", nullptr}, {"stop", nullptr}, {"notes", ""}}}, {"functional", {{"start", "bash x.sh full"}, {"readyPath", "/"}, {"exclude", Json::array()}}}, {"slots", {{"dir", nullptr}, {"start", nullptr}, {"stop", nullptr}, {"memMb", nullptr}}}}; g.slotMode = false; g.slotProblems.clear(); g.loginFixture = std::nullopt; g.stacks = std::make_unique(std::vector { {{"id", "the stack"}, {"appUrl", "http://localhost:1"}, {"apiUrls", Json::array()}, {"dbUrl", g.cfg.at("supabase").at("dbUrl")}, {"login", nullptr}, {"slot", false}}}); g.environments = Defaults(); g.environments["repo-bug-prover.md"] = "supabase"; std::vector logs; g.log = [&](const std::string& line) { logs.push_back(line); }; auto preflight = [&](const std::string& harness, bool dryRun) -> std::pair, std::string> { g.a.harness = harness; g.a.dryRun = dryRun; try { g.InstrumentPreflight(std::vector {"repo-bug-prover.md"}); return {std::nullopt, ""}; } catch (const Run::Preflight& e) { return {3, std::format("preflight: {}\n", e.what())}; } }; const auto [refusedOc, whyOc] = preflight("opencode", true); preflight("claude", true); const auto [dead, whyDead] = preflight("claude", false); Check("preflight: the opencode harness refuses a lens with the database (exit 3); a dry run names the masked URL and probes nothing; a database that does not answer stops the run before its gate (exit 3)", refusedOc == 3 && whyOc.contains("needs the claude harness") && std::ranges::any_of(logs, [](const std::string& x) { return x.contains("dry run") && x.contains("postgres:***@"); }) && dead == 3 && whyDead.contains("does not answer") && whyDead.contains("(bash x.sh full)") && !whyDead.contains(":postgres@"), whyDead); fs::remove_all(td); return Failures == 0 ? 0 : 1; }