feat(modes): the kernel modes - a patch series and a mailing-list reply

Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.

The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
This commit is contained in:
Jorijn van der Graaf 2026-10-31 22:56:12 +01:00
commit 339f4b9b40
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
46 changed files with 5732 additions and 362 deletions

View file

@ -6,6 +6,7 @@ import :Dispositions;
import :Json;
import :Text;
import :Platform;
import :Plan;
import std;
namespace fs = std::filesystem;
@ -48,6 +49,21 @@ namespace Crafter::Review::Dispositions {
"If the grounds do not survive, return the finding WITHOUT dischargedBy and set contests {id, why} with the evidence - a contest is a claim and will itself be verified. "
"Record that verification inside the finding's evidence field. For a refuted entry you agree with, return a note kind=refutation-verified with its id instead of a finding. "
"An entry with no matching finding of yours: ignore it - nothing is owed for it.";
// The kernel pipeline's rules, where the owner is Gate 5 and the
// evidence is the ledger, the captures, lore and the tree.
constexpr std::string_view KernelRules =
"Rules: if you detect a finding one of these entries names, STILL REPORT IT and set dischargedBy to its id and its unit id in items:[] - detection never changes, only disposition, and Gate 5 must see it. "
"Before setting dischargedBy, VERIFY that entry's grounds against its cited evidence (the ledger, captures/, lore via utilities/lore.py, the tree). "
"If the grounds do not survive, return the finding WITHOUT dischargedBy and set contests {id, why} with the evidence - a contest is a claim and will itself be verified. "
"Record that verification inside the finding's evidence field - do NOT emit disposition-review notes (that kind belongs to the persona lens). "
"For a refuted entry you agree with, return a note kind=refutation-verified with its id instead of a finding. An entry with no matching finding of yours: ignore it - nothing is owed for it.";
constexpr std::string_view PersonaRules =
"Rules: for EVERY entry above except kind gate0, return one note kind=disposition-review with its id, wouldComment (would this reviewer comment on the item as the artifact stands?) and why. "
"If one of your own findings is the item an entry names, report it with dischargedBy set to that id and its unit id in items:[] - it does not block.";
bool IsKernelLens(std::string_view lensFile) {
return Plan::IsLens(lensFile) && Plan::LensOf(lensFile).kernel;
}
}
std::vector<Json> Load(std::string_view path) {
@ -67,7 +83,7 @@ namespace Crafter::Review::Dispositions {
return out;
}
std::vector<Json> Classify(std::span<const Json> entries, std::string_view hash, const fs::path& artifact) {
std::vector<Json> Classify(std::span<const Json> entries, std::string_view hash, const fs::path& artifact, std::string_view mode) {
std::vector<Json> rows;
for (const Json& entry : entries) {
if (Dyn::Equal(Dyn::Get(entry, "hash"), Json(hash))) {
@ -75,7 +91,7 @@ namespace Crafter::Review::Dispositions {
continue;
}
const Json& carry = Dyn::Get(entry, "carry");
if (carry.is_boolean() && carry.get<bool>() && Dyn::Truthy(Dyn::Get(entry, "anchors"))) {
if (mode != "reply" && carry.is_boolean() && carry.get<bool>() && Dyn::Truthy(Dyn::Get(entry, "anchors"))) {
bool ok = true;
std::vector<std::string> details;
for (const Json& anchor : Dyn::At(entry, "anchors")) {
@ -96,7 +112,8 @@ namespace Crafter::Review::Dispositions {
}
rows.push_back({{"id", Dyn::At(entry, "id")}, {"status", ok ? "carried" : "lapsed"}, {"detail", Dyn::Join(details, "; ")}});
} else {
rows.push_back({{"id", Dyn::At(entry, "id")}, {"status", "lapsed"}, {"detail", "hash mismatch; carry disabled or no anchors"}});
rows.push_back({{"id", Dyn::At(entry, "id")}, {"status", "lapsed"},
{"detail", mode == "reply" ? "hash mismatch; no carry in reply mode - re-bind the entry to this hash" : "hash mismatch; carry disabled or no anchors"}});
}
}
return rows;
@ -112,13 +129,18 @@ namespace Crafter::Review::Dispositions {
return out;
}
std::string Block(std::span<const Json> inForce, std::span<const Json> rows, std::string_view lensFile, std::string_view hash) {
std::string Block(std::span<const Json> inForce, std::span<const Json> rows, std::string_view lensFile, std::string_view hash, std::string_view subsystem) {
const bool isPersona = lensFile == Plan::PersonaLens;
const bool kernel = IsKernelLens(lensFile);
const std::string_view ownerGate = kernel ? "Gate 5" : "Gate 4";
std::vector<const Json*> visible;
for (const Json& entry : inForce) {
const Json& lenses = Dyn::Get(entry, "lenses");
if (!Dyn::Equal(Dyn::Get(entry, "kind"), Json("refuted")) || (Dyn::Truthy(lenses) && Dyn::In(Json(lensFile), lenses))) visible.push_back(&entry);
if (isPersona || !Dyn::Equal(Dyn::Get(entry, "kind"), Json("refuted")) || (Dyn::Truthy(lenses) && Dyn::In(Json(lensFile), lenses))) visible.push_back(&entry);
}
const std::string head = std::format("DISPOSITIONS IN FORCE at hash {} - the register is the authority. Nothing outside this list discharges anything.", hash);
const std::string head = std::format("DISPOSITIONS IN FORCE at hash {} - the register is the authority.{}", hash,
subsystem.empty() ? std::string(" Nothing outside this list discharges anything.")
: std::format(" A waiver row in journal/{}/ledger.md for your lens that is NOT listed here is LAPSED for this hash and discharges nothing.", subsystem));
if (visible.empty()) return std::format("{}\n(none)", head);
const std::map<std::string, std::string> status = Statuses(rows);
std::vector<std::string> lines;
@ -145,7 +167,7 @@ namespace Crafter::Review::Dispositions {
if (Dyn::Truthy(Dyn::Get(d, "supersedes"))) line += std::format("\n supersedes: {}", Text(Dyn::At(d, "supersedes")));
line += std::format("\n anchors: {}", anchors);
if (Dyn::Truthy(Dyn::Get(d, "reaffirmed"))) {
line += std::format("\n REAFFIRMED by the owner {}x - final for this binding; a further contest is recorded for Gate 4, it does not block", Len(Dyn::At(d, "reaffirmed")));
line += std::format("\n REAFFIRMED by the owner {}x - final for this binding; a further contest is recorded for {}, it does not block", Len(Dyn::At(d, "reaffirmed")), ownerGate);
}
if (Dyn::Truthy(Dyn::Get(d, "contestRejected"))) {
line += std::format("\n contest REJECTED {}x after re-checking the cited fact - a repeat contest without new evidence is recorded, it does not block",
@ -153,6 +175,6 @@ namespace Crafter::Review::Dispositions {
}
lines.push_back(std::move(line));
}
return std::format("{}\n{}\n{}", head, Dyn::Join(lines, "\n"), Rules);
return std::format("{}\n{}\n{}", head, Dyn::Join(lines, "\n"), isPersona ? PersonaRules : kernel ? KernelRules : Rules);
}
}