SANDSCOPE / LORA
Every semantic decision in this system is a regular expression
Whether a question demands a number, whether a passage supplies one, whether an action is destructive, whether a citation supports the claim citing it — all four are pattern matches. Negation, paraphrase and entailment are precisely what a regex cannot do.
Status: designed and in progress, not shipped. The design and the implementation plan are written and the training spine is being built, on a branch that has not landed yet — so they are cited below by path rather than linked, because a citation that 404s is worse than none. No adapter is serving. The two models currently in production — the evidence classifier and the cross-encoder re-ranker — are ordinary fine tunes and predate this work. This page describes what is coming and why, and it will say so until that stops being true.
What the regexes structurally cannot do
This is not an oversight. It is the zero-LLM-at-request-time discipline, and it has been paid for: the first version of _CONTAINS_A_VALUE was a plain \d, matched “Tier 0” and “Severity 1” everywhere, and so passed while catching nothing.
| Decision | Today | What it cannot reach |
|---|---|---|
| does this question demand a quantity? | _DEMANDS_A_VALUE | a demand phrased outside the listed nouns |
| does this passage supply one? | _CONTAINS_A_VALUE | “a fortnight”, “two business days” |
| is this proposed action destructive? | _DESTRUCTIVE, _IRREVERSIBLE | “take node-3 out of the pool”; fires on “do not restart” |
| is this claim cited? | uncited_claims | whether the cited chunk supports the claim |
A small fine-tuned encoder does exactly this, while preserving every property the architecture requires: trained offline, served as ONNX, no framework at runtime, no API call, deterministic, tens of milliseconds.
Why LoRA specifically — including what it does not buy
- One base, four tasks. All four decisions are sequence or sequence-pair classification. Full fine-tuning ships four ~140M models; LoRA ships one base and four adapters of roughly a megabyte each.
- Capacity match. Each task has hundreds to low thousands of constructed examples. Full fine-tuning 140M parameters against 2,000 examples overfits, and this project has already been burned by exactly that — ADR-0013’s operating point looked excellent on one pass and failed held-out folds at 6.1% against a 5% budget. LoRA’s low-rank constraint is the regulariser.
What LoRA does not buy here, stated plainly: the serving-side benefit. Each adapter is merged into the base and exported to ONNX, so what ships is four ordinary models — not a base plus swappable deltas. The saving is training-side. That is a legitimate reason to use LoRA and it is a different reason from the one most people assume, so it is written down rather than implied.
The four adapters
| Adapter | Replaces | Task shape |
|---|---|---|
| A1 claim-support | uncited_claims | (claim, chunk) → entailed / not |
| A2 value-demand | _DEMANDS_A_VALUE | question → demands a quantity |
| A3 destructive-intent | _DESTRUCTIVE, _IRREVERSIBLE | proposal → destructive |
| A4 instruction-smuggling | nothing — T-15 is unguarded | body → carries injected instructions |
A1 is the one that changes what the product can claim. verify currently checks that a claim has a citation; it has never checked that the citation supports it. That gap is the product’s central promise.
Labels are true by construction, never a model’s opinion
ADR-0010 forbids model-assigned labels, on the grounds that ground truth which is itself a model’s opinion makes the resulting claim unfalsifiable. Every label is a property of how the example was built.
- A1. A sentence extracted from chunk C, paired with C, is supported by construction. Hard negatives: the same sentence with a template negation applied so the label flips, and the same sentence paired with the highest-ranked non-source chunk. Trivial lexical overlap is the failure mode here, so the negation arm is what makes the task non-trivial.
- A2. The label is read from the question generator’s slot, never from
_DEMANDS_A_VALUE. Labelling from the regex would teach the model the regex and measure agreement rather than correctness. - A3. Proposals are synthesized as action × target tier × reversibility, and the label is the slot rather than the surface string. The surface is then paraphrased without touching the slot, so the regex breaks while the label holds. This is the adversarial arm and the reason the task exists.
None of it may call a model, and a test asserts that by parsing the module rather than trusting the author.
The number that would have been a lie
A1 trains on sentences from the corpus but serves on sentences a model wrote. Those are different distributions, and a number from the first does not transfer to the second.
The citation table already stores claim_text and chunk_id for every completed run — real model-written claims paired with the chunk actually cited. That is the serving distribution, recorded before anyone needed it. A1’s headline number is measured there, on hand-adjudicated ground truth, and reported separately from the constructed test set. The constructed number measures the task; the recorded one measures the product.
Serving stays unchanged: ADR-0009 means no torch, transformers or peft in the serving image. Adapters are merged, exported to ONNX, and run through the same runtime as the re-ranker.
Where this work came from
The discipline above is not native to machine learning practice — it is what the delivery roles on this project demanded. Labels true by construction is a Business Analyst’s objection to unfalsifiable evidence. Measuring on the recorded serving distribution rather than the convenient one is a QA Lead refusing a number that flatters. ADR-0013 exists because a held-out fold contradicted an operating point that had already been accepted.
That review process was written down as a charter, replayed against this repository’s real history on the council page, and then extracted into Charter — an open-source MCP server that enforces the same rules on any repository, for anyone. A role must produce a machine-checkable artifact before it may sign off, and no role may sign off its own work.
So the adapters are governed by the tool the adapters’ own project produced. When A1 ships, the number it ships with will have been argued over by roles that were required to disagree in public — and the record of that argument will be in the repository next to the model.
The design is docs/superpowers/specs/2026-09-02-lora-adapters-design.md and the plan is docs/superpowers/plans/2026-09-02-lora-spine-and-claim-support.md. Both land on main when the branch does, and this page will link them once they resolve.