Appearance
Facts — the system in single sentences
Load when: writing about this system for people, or needing one true line about a part of it.
Every line here stands alone. No this, no it pointing at a neighbour — each is readable out of order, because that is how they get used: on a card, in a post, in a page where they move.
A line here repeating its chapter's measurement is the design, not a duplicate. Standing alone is the requirement above, and a line that pointed at a chapter instead of carrying the measurement would be unquotable — which is this file's only job. So the chapter holds the rule and this file holds the line, and where a chapter wants the narrative short it cites the entry number instead (pipelines → 273). Written down 2026-09-18, after a deletion lens read eight new entries against their chapters and proposed cutting one side: declined, because the duplication is between a rule and a quotable sentence, not between two homes for one rule.
Every line is also true and traceable, which is the whole constraint. A fact that overstates is worse here than a fact that bores, because this file is what other writing quotes — and a claim quoted out of a marketing page becomes a promise nobody checked. When a rule changes, the line changes with it.
The premise
- One private git repository per project, and every entity inside it is a file.
- Clone the repository and the project comes with it — the team, the process, the history, the budget.
- Delete every cache and the system rebuilds it.
- There is no export feature because there is nothing to export from.
- Nothing load-bearing lives in a chat log or anyone's memory.
- One repository is one project; several deliverables inside it are areas, not projects.
- The tree you work in is not always the project's repository.
- Because nothing load-bearing lives in the session, the session is replaceable.
Work
- A task has an id, an assignee, a thread, runs and a cost; a checklist line has none of those.
- An id is six characters from a 32-symbol alphabet, and it is never reused.
- Ids are minted by a script that skips what the tree already uses, because a model asked for a random id is not a random source.
- Links point at the id and never at the name, which is what makes renaming safe.
- There are six status categories, and the project names its own stages inside them.
blockedis not a status — a blocked task is started, with a blocker.- A stage is a step of a pipeline; a wave is a barrier between sibling children.
- Two children in the same wave never own the same file, and ownership is assigned at decomposition rather than discovered at merge.
- Relations are typed pairs with one side stored and the other generated.
- Priority is opt-in, and dates beat priority.
- Priority is not the order.
- Raw intake lands in triage, off the board, with four dispositions: accept, decline with a reason, duplicate, snooze.
- A parent that spans three crafts belongs to nobody and is left unassigned.
- Progress is derived from the atoms every time and never stored as a rollup.
- A task that cannot finish in one run is decomposed rather than hoped through.
- Every task states what does not count as done — a plan instead of a result, a quietly narrowed scope, one example treated as verification.
- A type proposes its task's fields at its birth — only the few its craft's own standard names, each carrying what it means and when to set it.
Nothing moves by itself
- A closed blocker does not start the work.
- All children finishing does not close the parent.
- A slipped task does not move a date.
- Everything surfaces as ready and waits.
- Automatic transitions are how boards begin to lie.
- The one exception is a parent with no definition of done of its own, because closing an empty folder asserts nothing.
The team
- A project starts with one advisor and nothing else.
- The advisor is Opsinist itself — the session you are talking to.
- There is exactly one advisor, and a validator refuses a second.
- A role is created the moment a task needs a craft nobody has, and the reason is recorded then.
- An unused role still costs: it sits in the roster, in search results, and in every "who should do this" decision.
- A team assembled before the work is a guess about the work.
- There are five kinds of role: advisor, worker, expert, persona, human.
- A human may hold an assignment — taken, never handed out.
- Nothing dispatches a person, because a queue that can push work onto a human is a queue that will.
- A grade decides routing and never enters the instructions as an identity.
- A model told it is junior will act junior, producing worse work on purpose.
- Never demote a role to make it cheap — its cost history becomes unreadable.
- You address the group and its routing rule decides who; exactly one may hold an assignment.
- A role's load is budgeted as a share of the context window, not as a fixed number.
- A role carrying twelve skills is worse at each of them than a focused one.
- Caching makes breadth cheap; it does not make it good.
- The advisor's own model is the one setting the cascade cannot reach, because the advisor is the session.
Evidence
- Every claim carries how it is known: measured, cited, recalled, or a judgement call.
- A lower rung never borrows a higher one's authority.
- The rung travels with the claim, so agent B cannot promote agent A's guess by quoting it.
- An argument without a source is an opinion.
- Signal about people uses a second ladder — live, twin, validated persona, proto — and the two are never pooled.
- Three live interviews and twenty synthetic runs are never "23 responses".
- A hundred synthetic respondents are one bias repeated a hundred times.
- Synthetic audiences are legitimate for surfacing angles and illegitimate for percentages.
- A percentage is refused before the run, not disclaimed after it.
- Every persona carries two to four named biases, and each one names its grounding.
- Persona verdicts are direction-only: which concern appeared, never a magnitude.
- Agents run bias checkpoints on themselves — anchoring at framing, agreeableness at output.
- Is the search phrased to confirm rather than to find? is a question an agent asks itself.
Freshness
- Every recorded fact that can change carries the date it was checked.
- Past its recheck, a fact is unknown rather than fine.
- Prices and current limits are fetched at the moment of use and never cached.
- A stale tick is worse than no tick, because it makes someone skip the check they should have run.
- Meeting a stale claim mid-task is a procedure: re-verify, or block — never quote it.
- A snapshot of an external page is a cited claim, honest exactly as long as it is dated.
- Research rots as a whole document: a pricing study from six months ago is not a fact.
- A release that ships a stale price or a dead link ships a small lie.
Gates
- Four kinds of action route to the owner: spending, leaving the repository, destroying, and changing the shape of the team.
- The fourth is the one everyone forgets, and it is how a project gets quietly rebuilt around someone else's intent.
- A gate is a property of the action, not of who performs it.
- The advisor is not exempt from any gate.
- A blanket "yes" covers only the ungated.
- Every gate declares what actually holds it: a request, a validator, a hook that ships with the plugin, the git host, the runtime, or nothing.
prose-onlymeans nothing enforces it, and those rules are listed by name.- A gate believed in but not enforced is worse than a stated rule.
destructiveis always-ask in every preset and cannot be preset away.- Loosening exists only as a grant, which is visible while it lives and expires by its own terms.
- A grant's expiry is evaluated at the gate, not by a timer, because nothing runs while nobody is working.
- The cascade is one-way: a task may raise the bar and never lower it.
- Nobody edits the bar they are measured against.
- A review goes to someone other than the author, because models judge their own output generously.
- Self-editing is proposed, never self-merged.
- A repository being taken over cannot carry the preflight that would constrain the takeover, so those gates travel with the plugin as hooks.
- An outward act — a push, a release, a publish, a deploy — is stopped by a hook that names two doors: the owner runs the command, or switches the gate off on purpose; the retry is not a door.
- A rule spoken to be remembered is refused a home in the harness's private agent memory — the refusal names the files workers actually read.
- In a takeover, a mutating call made before the debt list exists is refused, and a run that presented deferrable findings without writing them down is stopped.
- A guest trips neither gate, because a guest owes no debt list at all.
- No gate decides whether the owner said yes: any evidence of approval could be written by the party the gate constrains.
Cost
- Cost is recorded as four token numbers, never one total.
- Cache reads are the overwhelming majority of tokens, and a single total hides the only lever that moves the bill.
- A run also records what it spent outside the model, because two hundred generated images cost money and no tokens.
- Five of the ten cost slices measure waste rather than spend.
- One slice answers what was spent on runs that produced nothing.
- Another prices not getting it right the first time.
- Another asks whether an expensive setting bought anything.
- Another compares skills declared against skills used.
- The advisory conversation is a separate bill from the work.
- A budget changes what gets recommended in the first place, not only what gets stopped at the end.
- With no budget declared, the system assumes no money and says so.
- Credits and free months are runway, not income, and the advice names the cliff.
- The dispatcher records the numbers, because a worker does not reliably see its own usage.
- A task that closes with no run record naming it is warned about at the moment it closes, because cost is stored once at the run and every other number is derived from it.
- That warning names both honest answers — write the record, or say in History that a person did the work — so it can be answered rather than lived with.
Recovery
- A run that dies resumes instead of restarting.
- Recovery reads committed state from the repository, not from a session that no longer exists.
- Work already applied is never redone.
- A run that never returned is marked interrupted, and the task visibly regresses rather than sitting done-ish.
- A board that went backwards overnight is reporting a failure, not somebody's edit.
- Agents commit incrementally, around two thirds through the context, because a run that dies takes everything unwritten with it.
- Three attempts at the same error is a signal, not a reason to try harder.
- A third review round on the same point is a specification problem, not a review problem.
Where things live
- Six layers — documentation, work, conversation, team, telemetry, results — ordered by what they mean to someone with no agents at all.
- Which of them land in the repository is one position on a ladder, not six switches.
- A complete copy is always local, so the choice can be made after the work is done.
- Fixing an issue in someone else's library leaves not one of our files in their tree.
- In a repository that is not yours, the record still gets made — elsewhere, and you are told where.
- Guest work is where a record matters most, because the checkout may be deleted the moment the work lands.
- When ownership of a repository is unclear, the system treats you as a guest.
- A guest produces no unsolicited debt list for maintainers.
- A manifest in the repository says where each layer lives, so a clone always gives the map even when it does not give the contents.
- Deleting a project lists what it found per destination and names separately what it cannot delete at all.
- An operation that cannot reach a declared destination stops rather than half-finishing.
- Everything the machinery owns lives under
_ops/— one directory, named to sort first and collide with nothing — and the root stays the craft's. - The layout migrator moves a flat project as history-preserving renames, refuses a dirty tree so the move is its own diff, and leaves what it does not recognise where it is, named.
The toolkit
- A routine repeated twice becomes a skill; once is a task, and "we might need it" is neither.
- An imported skill is screened as untrusted code and untrusted instructions.
- A skill's text becomes part of what an agent believes, which is why it passes a gate before it attaches.
- Fitting a skill to a role means dropping sections, never rewording them.
- Compression preserves commands, paths, numbers and security rules verbatim.
- If fitting fails, the role gets the original, never a truncation.
- A skill that earned its keep across two projects can be de-identified and released on its own.
- A tool entry records where the free tier ends, in the unit that will actually bite.
- Throttling, hard-stopping and charging automatically are three different risks, and only the third surprises a budget.
- A resource without a stated
whyis a bookmark, and nobody removes it because nobody knows what it was for. - A resource serves every flow that meets its need — filed by one flow, scoped to none, read wherever relevant rather than re-asked for.
- A webhook URL is a credential, because holding it is enough to spend money under the project's name.
- Secrets are registered by reference — name, purpose, prefix, expiry — and never by value.
- Automations create work and never move anyone else's.
- An automation dry-runs before it runs, and its failures are visible.
Waiting, and what it costs
- Work that would take minutes leaves the turn, so the conversation keeps going.
- An agent asked something long says it is going to look, and comes back with the answer.
- A reply that arrives late with substance beats a silence that looked like a reply being typed.
- An estimate being overrun is said out loud, because silence that contradicts a promise reads as a crash.
- Two things never go to the background: work the next sentence depends on, and work that will stop at a gate.
- A helper is chosen at the tier its own work needs, never at its parent's.
- Search, extraction and verification run a tier down or further.
- "Same as me" is the most expensive default available, and it hides in the bill as ordinary work.
- Every helper that ran is named in the record with its tier and what it was for.
- An answer produced by three helpers is never reported as one agent's.
- Before anything likely to exceed thirty seconds, you are told what is happening and roughly how long.
- Silence during a long run reads as a crash, which is why there is a progress line at each meaningful completion.
Leaving and coming back
- There is no log-out: a session ends when you close it, and the advisor cannot end its own.
- What ends a session cleanly is a wrap-up, and the words that start it are ordinary — "I'm done for now".
- The wrap-up is offered when the signals are there, not remembered by you.
- It is three writes: the tail to its thread, applied work committed, decisions recorded.
- After that the session can be closed from anywhere, because nothing is left in it.
- Clearing a terminal costs nothing, because the transcript is a source and never a dependency.
- Opening the project again — same tool or another — starts with the arrival summary rather than a blank prompt.
- A session that ended badly costs a summary line, not the work.
Method
- Every real decision runs one loop: frame, search, compare, choose, check it survives being wrong, record, act.
- If a small error would flip the decision, the decision is undecided, and saying so beats faking precision.
- Find the process before the tools, then find a tool per step, by function.
- A literal "designer" finds nothing; "map the user journeys" finds everything.
- A step with no tool is a gap, written as one, never papered over with improvisation.
- Free, then open source, then self-hostable, then embeddable, then drivable by an agent — a paid option earns the exception with a recorded reason.
- "Drivable by an agent" is not last by accident: a tool only a human can operate makes the owner the bottleneck.
- Licensing is settled before the first line of work, because in licence-heavy domains it decides what you may ship.
- Not knowing is normal; not looking is the failure.
- Asked what we have, the registers are the first source and the web is where the register ran out.
Talking to people
- Two questions are never skipped: how much you want to be in the loop, and who may direct this.
- An agent once ran an entire project hands-off because the first one was never asked.
- Nobody is asked to choose a command; the entrance is read from what is there.
- Anything readable from the ground is read, never asked.
- A defensible default is stated as a filled-in form needing a nod, not asked as an open question.
- Over-serving someone who asked for very little is the most common failure in practice.
- A quick job gets three questions, one or two agents, build and review, and deliberately none of the machinery.
- What a small job does not get is written down rather than left to judgement.
- No praise by default, and disagreement comes with an alternative.
- "Built" and "works" are different claims, and the system says which one it is making.
- Advice arrives while the decision can still change for free, because a warning delivered after the work is built on it is just criticism.
Outside software
- Ship is the go-live moment whatever you make: an episode published, a production batch sent, a finding published.
- Urgent means something different in every medium, and it is defined per medium.
- A chip maker has no data flows, a channel has no sprints, a bakery has no deploys.
- If a sentence would sound absurd to someone outside software, the sentence is wrong, not the reader.
- There is no per-industry catalogue, because the moment one domain gets its own list this stops being a method.
The system on itself
- A change to the machinery goes through the same tasks, gates and history as the work.
- Behavioural scenarios run against fixtures built by a script, so a suite is re-run rather than reconstructed.
- The player in an eval never sees the rubric, and the judge never wrote the transcript it grades.
- Evals are scored as a pass-rate, because one run of a nondeterministic actor is an anecdote.
- The eval pass-rate is a regression detector and is deliberately not treated as a measure of success.
- Four lenses read every change of consequence — deletion, adversarial, contradiction, cold-read — by someone who did not write it.
- A lens that found nothing says so, because a silent lens is indistinguishable from a skipped one.
- Validators refuse duplicate ids, dangling links, ageing claims, orphaned templates and a rule living in two files.
- A rule kept in two files goes stale in one of them.
- When a rule does not hold, the repair is a form — a list, a required field, a gate — and never a stronger sentence.
- That last one was measured rather than argued.
The ladder and the door
- Where the description of work lives is a ladder: the value names the cut, the rungs below are presumed, and a skipped rung is declared.
- A spec document and a failing test are one cut, not two modes to choose between.
- An exemplar is validator-checked or gauge-checked, and a gauge needs a judge who is not the author.
- The kind of work owns the default cut, proposed from the craft's own standards at the type's first wave.
- A stage changes through one door, which refuses with the reason, records the move — and never starts the next step.
- A dispatched worker receives its legal moves generated from the pipeline's own block, never recited from memory.
- A run's strategy resolves like its model does, lands on the record with its source, and the selector reads fields, never vibes.
- Silence on a request does only what a grant, written in advance, allows.
- A fact is cited to its place with a content-hash, so a passage that moves under the citation turns the fact unknown rather than quietly wrong.
- Compaction is safe for exactly what is already in the repository, and the three writes come before the shrink.
- Where the runtime can resume a dead session, the transcript is a readable source once — salvage, never the record.
- A gap found mid-build goes to the group that owns the invalidated artefact, and nobody edits what another craft is standing on.
- A release names its rollout, guardrail measures own the halt, and expansion surfaces as ready rather than advancing itself.
- The kill switch is named before the first user sees the change, whatever the craft calls a kill switch.
- A survey instrument matches its layer — the step, the scenario, the software, the brand — and reading one layer with another's tool is the trap.
Assets and their recipes
- A generated asset records the model, the prompt, the seed and the reference image it was made from.
- A generated image whose recipe was not written down cannot be made again, and the set it belongs to drifts without anyone deciding to let it.
seed: noneis an accepted answer, because some models expose no seed and an honest gap beats a fabricated number.- A style preset library is a vocabulary for talking to the owner, not the thing that makes two images match.
- Reading a lost prompt back out of an image is salvage — what comes out resembles the original and is not it.
- A transcript is taken from the caption track that already exists before any audio is sent to a model.
- A deck kept as text in the repository can be diffed, reviewed and gated; one kept as a binary cannot.
When the executor cannot
- A worker missing a capability keeps the task and asks for one operation, because a task handed to a person has no runs and no capacity and its progress goes invisible.
- A request has five kinds, and the fifth is a relay: one operation the worker cannot perform, and nothing else.
- A relay carries the payload verbatim, the predicate and the destination — or the commit is refused.
- The predicate is written before the payload, because a check written after the artefact arrives is written to fit it.
- Production and perception fail separately, which is why a model that cannot draw an image can still judge one.
- Where the worker cannot perceive the result either, it says so instead of performing an inspection it cannot do.
- A capability gap is met mid-run, unlike every other missing capability, which is announced at dispatch.
- The second time the same capability is missing, it stops being an escalation and becomes either a wired tool or a person on the roster who owns that surface.
- A standing arrangement left as an escalation ages and surfaces every time, until the surface built to catch real trouble is the one nobody reads.
Arriving where there is no repository
A directory that is not a git repository is told so at session start, because a person who has never run
git initcannot act on a silence.The fact names what the fix costs — one local command, nothing leaving the machine, undone by deleting one directory — rather than asking a question only someone who knows git can answer.
A folder that already holds work is told that
git initmoves and changes nothing, because that is the fear that stalls the takeover.The no-repository fact is said once per directory and never in the home directory, because a hook that speaks in every folder is one people learn to ignore.
Auditing a tree with no history is a thinner job than auditing one with history, and saying so beats performing the fuller one on evidence that is not there.
A plugin's scope is where it is declared, never where its files are: the code lives in one machine-wide cache that every project shares.
A project-scoped plugin declaration without its marketplace tells a clone to enable something without saying where to get it.
A relay also carries what to return with the result, and that field is caught downstream rather than at the relay: without the model and the seed the recipe cannot be filled, and it is that commit which is refused.
A council's synthesis declares what it was made of — angles, voices, and whether they came from one provider — because a warning that agreement across one model is one bias repeated is a warning, while
provider: oneprinted above the verdict is the reader seeing it.The strongest dissent is what a council is bought for: a panel that converged instantly measured nothing, and the agreement is the part that was always going to be cheap.
A move on the map carries the job it is hired for, written as a job story — when this happens, someone wants to do this, so they can get this — and the guard refuses a move added without one. A route is a how; the job is the why somebody walked it, and a roadmap reading a map of routes alone proposes routes nobody asked for.
A market figure carries where it came from and when, or the guard refuses it — and
unknownis an accepted answer. The gate does not ask a project to have numbers; it asks that a number, once written, be traceable, because a market size is the easiest thing in a project to invent and the hardest to check.The record is written while the work happens, not filed when it finishes — a run does not choose when it ends, and a limit, a crash and a closed terminal each land on whatever was still only in the session's head. The outcome is the last field filled, never the first.
A finding does not become a rule the day it is found: a dated line costs nothing, a second occurrence earns it a task, and a promotion into the guide waits a week — spent doing other work, because what still reproduces with the panic gone is about the system. Repairs never wait; the ladder governs lessons.
Three attempts bound failure, and two runs that disagree bound contradiction — the worse state, because every run inside it looks like a success. The work stops at the second disagreement, and what escalates is that the question is unstable, never which run was right.
A run may not end leaving the machinery uncommitted — in a project this system operates, in a session that opened it, the hook refuses the ending once and names the files. It watches
_ops/and the package manifests, because those are what every other gate keys on: each is enforced at the commit, so work that stops short of one is held by prose alone.A commit that adds a dependency names it in the decision log, with what it replaces and what was rejected — the guard asks for the dependency's own name, not a keyword, because a gate satisfied by vocabulary teaches people to sprinkle words. A version bump is not a new dependency.
The rung above choosing a tool is asked where there is no code at all: a row added to the tooling register is refused unless something says what it replaces, because a supplier, a subscription and a stock licence arrive in a minute and are maintained for a year exactly as a library does.
we had nonepasses — outside software that is usually the true answer, and a gate that would not accept it teaches people to invent a predecessor. It refuses rather than warns because the warning was measured at 0 of 5 and the refusal at 2 of 5 (2026-08-22).A tool an agent can reach is weight it pays for, not only a thing it can do: where a runtime loads every tool's schema before the first word, forty tools are tens of thousands of tokens spent on a session that says hello. That is the same budget as a skill's
core_budgetand a role's always-loaded weight, arriving from outside the repository — so the register's question is not only what can this reach but what does reaching cost when nothing uses it. Runtimes have begun answering it themselves, by listing tools by name and loading a schema only when one is called for; where a runtime does not, the cost is real and the remedy is fewer servers wired, not a cleverer wrapper.More documentation, iterated without a human curating it, plateaus and then hurts. Runs latch onto different parts of a grown document or ignore some of it, and the rate stops improving while the text keeps growing. The instinct when a run gets something wrong is to explain more; that is the move that stops working first, and what the document needs is someone deciding what comes OUT. Measured by Sanity Labs on their own design-system documentation and published 2026 (
catalogue, Does the design system survive an agent?) — their models, their task, not this project's. It is the noise rule this system already applies to checkers and to migrated backlogs, arriving at the documents themselves.A multi-step flow a run must complete UNATTENDED is a form that does not hold — a run walked through a configuration wizard abandons it partway, while a pre-written chunk of what that wizard would have produced held at 93–100% on the stronger tiers (Sanity Labs, 2026, their models —
catalogue). This is not the progressive interview, which has a person answering at every turn and holds because they are the thing that forces the next step; it is the case where nothing is present to force one. A refusal and a template hole both survive being left alone. A conversation does not.The same document produces very different rates by tier, and improving it does not close the gap. One before-and-after on one team's design-system docs — Sanity Labs, 2026, their models and their task (
catalogue): 3% → 47% on their weakest tier, 20% → 90% in the middle, 40% → 100% at the top. Every band improved and the floor stayed a floor. So a document is not good or bad, it is good for a tier, and a rewrite that triples the weak tier can still leave it failing half the time. State the tier with the rate, and do not price work at the top band's number.Whether a document WORKS is measurable, and measuring whether a rule holds does not measure it: a rule is measured by running the situation and counting the outcome, a document by giving several runs the same task with it and counting what came back. The counts say where, never why. The method, the measurements it uses and why this project has not run it are in
LATER.md, Nothing here measures whether a DOCUMENT works.A ledger that records how a run ENDED cannot see two runs disagreeing about what is true, and that is the worse failure — every run inside it finished, so every run reports confidently. Two workers answering one question opposite ways both write
completed, and the contradiction leaves no trace at all. Measured on this project 2026-08-28: the rule bounding it had been written in nine files and enforced by nothing, because there was no field holding what a run concluded — only how it stopped. Adding that field made the bound countable, and five mutants of the resulting gate each fail assertions the honest version passes. The general shape: a rule that names a state nothing records is not enforced and cannot be, however many times it is written.A guard that reads a format its own template does not produce is green because it read nothing, and that is worse than an absent guard: it issues a report on a check that did not happen. Measured 2026-09-05 on a live migration — two checks parsed YAML frontmatter while the shipped role template writes
**Type**: advisorand a markdown table, so a role written from that template was invisible to both: two declared advisors, one found; nineteen skills, zero counted. The pair had already been repaired once, for the directory it looked in, and the format mismatch survived the repair untouched. The general question to put to every check that greps a file the corpus also ships a template for: does this read the shape that template writes? — and the answer is a fixture of each shape, not a reading.A deferral is kept honest by its trigger, and the trigger fails in ways the deferral cannot see — the last of them being the reader. It can be absent, which every list already guards against. It can be unreachable: a condition naming something that does not exist, which reads as diligence and never returns — measured 2026-09-06, an entry waiting a fortnight on a file this repository does not have and by its own rules should not. It can have already fired while nobody looked — an entry whose condition was "the next full round after 0.2.7", eight releases old at the reading. And the reader can be wrong about which of these happened: the same audit closed an entry believing its trigger had fired, on a page whose closing line says the measurement was never taken and beside a paragraph in that same entry saying so too. Three lenses caught it the same day. Then the correction did it again — the rewritten trigger named a condition a paired run had satisfied a fortnight earlier, six lines above where it was written, and a fourth lens caught that. Reading a trigger against reality is not a thing you do once and are then good at; it is the same act, owed again, by whoever writes the next one. So a trigger is read against the evidence file, never against its own summary of what would satisfy it — and read on a cadence, because an entry that reads well is exactly the kind that is never re-read.
A repair written in answer to a review is the part of a change least likely to be read, and its author is the worst-placed person to read it. The review round reads what was drafted before the findings existed; the repair is drafted after them, at speed, by the person the findings have just convinced. Measured over three releases: a round whose worst finding was a regression in the repair it had just prompted (2026-08-23); a repair where three of four adversarial findings were false refusals it had introduced (2026-09-05); and a repair that reinstalled the exact defect it was repairing — twice — found by the one lens pointed at the repair while three pointed at the range missed it (2026-09-07). So a review is not finished when its findings are answered; the answer is the next thing to read.
A register that cannot say what pulls against an entry is a pile with an index. Holding a source is not the same as knowing where it stands: two findings can sit in one file for a year, contradict each other, and never meet, because nothing ever asks. The repair is a field rather than a habit — each entry names what it must be read beside, and the two ways of saying nothing are kept apart: none found is a claim that someone looked, not checked is honest ignorance, and an empty field is neither. The field is symmetric, which is what makes it checkable — a one-way pair is refused by a script rather than noticed by a reader. Measured 2026-09-10 on twenty entries: two carried a comparison buried in a prose paragraph where nothing could read it back, and the most valuable answers were not disagreements at all — six sources that look opposed turned out to measure different things, and that resolution is what the rules downstream actually rest on.
A skill nobody tested is a hypothesis, and asking politely for the test measured zero. The instruction existed and was exact — every command a skill contains is run before the file is saved, against an input it must reject — and a scenario built to watch it scored 0 of 5, counted from transcripts across three rounds; one run declared itself tested by reading the manual, reproducing the corpus's own documented failure while the sentence describing it sat in the file being read. The repair is a field that asks for something a reading cannot produce: the defective input, what the command actually printed when it refused, and the date. You cannot paste output you never generated, and a passing case proves nothing, because a checker that reads nothing and a checker that finds nothing wrong return the identical silence. Where a skill runs nothing,
noneis the whole answer — gating those too would teach everyone to write the section without meaning it, which is the failure being repaired.A research answer that does not say how hard anyone looked reads as if someone looked hard Depth is invisible in a finished document: the same page can be twenty minutes or six hours and the reader cannot tell, so naming the rung before the work is offered as a price the owner agrees to. Three rungs named by what they buy — a direction, a defensible call, or something quotable in a year. Nothing here has measured whether stating it changes a run — so this is a judgement call, and it says so in the file other writing quotes.
Research is a task and its conclusion is not — they have different lifetimes, so they are different files. The task carries the cost, the depth and the definition of done, and it closes; the finding stays true until a named event retires it, is read long after the task is archived, and is where the next question starts. One file per question, because a topic never closes and a question does. It opens with what we now believe in a paragraph, which is the part read instead of the sources under it — an agent that needs the answer stops there, and the register is for whoever argues. The order to read them in is the order of the decisions waiting on them, carried by a field on each finding rather than a second list, because a second list is a list that lies.
A checker's false warnings are not noise around the signal — the signal stops being read at all. Measured 2026-09-10 on this repository's own structure check: thirteen warnings, eight of them false by construction — six comparing a superseded changelog entry's count against a corpus that had moved on, one charging a sentence with the sibling bullets that followed it, and one a plain misfire reading
mermaidas a counted noun inside "one mermaid edge". The other five were real, each one line long: a table row wrapped onto a second source line, a paragraph whose line broke before5.so markdown read an ordered list, a hyphenated word split by a line break, and a table row that had lost a cell to a row eight lines below it, counted twice because two rows were malformed. They were not buried — they printed second through sixth, under a single false one and above the other seven, and the wrapped table row had shipped in eleven consecutive releases since 2026-08-16. Position is not what hid them: a list known to contain warnings that can never be fixed stops being read at all, and then where the real ones sit in it makes no difference. The repair is to stop making the comparison that cannot be won, not to raise the threshold. That such a list gets a check switched off in the reader's head is the fear this is written against and has not been counted here; what was counted is how long five one-line defects survived near the top of one.What a project needs from the machine had nowhere to be written, so it was written nowhere. Measured on the 0.2.18 tag, 2026-09-11: the corpus named ffmpeg three times, all three on the catalogue's shelf as a tool to choose, and never once said where a project records that it needs one — and the only guard on dependencies, §4e, reads package manifests, which a system package never enters. The repair names a truth per need —
.mcp.jsonfor an MCP server,mise.tomlfor a runtime or a system package — and keeps only the why in the register, the guard holding the two to each other in both directions, because a second list of versions is two numbers that will disagree. Two measurements set its edges. On Claude Code 2.1.226 a variable missing from the environment is a warning and the server starts with the literal text${VAR}, so a placeholder likeYOUR_API_KEYis refused as firmly as a leaked token. On mise 2026.9.5 amise.tomlwith[tools]alone is read on any machine, while one carrying[bootstrap.packages]is not read at all untilmise trust— which is why trusting it heads the takeover's line, and why it is the owner's to say.The line between a routine update and a decision is the project's own pin — and the tool that reports it can report nothing and look finished. Python 3.12 → 3.13 is a minor number, and 3.13 removed nineteen standard-library modules (PEP 594); npm's own
outdatedputs the line where the project's range ends,wantedinside it andlatestbeyond. Read in mise's source on 2026-09-11: one field,latest, means the newest version inside the pin without--bumpand the newest at all with it, so the two answers merged would have filed a jump across the pin as routine — the first draft here did exactly that — and a tool whose lookup fails is dropped from the JSON with only a warning on stderr, so an offline run and a current one print the same{}. The report keeps the answers apart, says not checked for every lookup that failed, and ends by saying what it asked. Run the same day on this machine's docs site, it found one dependency in both directions — mermaid 11.16.0, with 11.17.2 inside its range and 12.0.0 beyond it — and said security was not checked, because osv-scanner is not installed here.A recheck trigger written in words waits on someone's memory — but one of the events it names is one the tree already records. Read on 2026-09-11, the guard held a finding's
Recheck whento being filled and to nothing else, so "when a source contesting this arrives" was caught, if at all, by whoever happened to remember the finding while filing the source. Yet the arrival was already written down: the register records a tension as a name in an entry'sReads against, and findings cite entries by id — so the trigger is a join over two files the project keeps anyway. It is the ingest cascade of a model-kept wiki (Karpathy's LLM Wiki, 2026-04-04) done as a refusal instead of a rewrite: no model re-edits fifteen pages; the commit that records the tension carries each finding on either end re-stamped or markedstale, or it does not land. Touching the file is not re-reading it — the suite's second mutant counts any edit as a re-read, and the guard as shipped refuses what that mutant lets through. The suite found one of its own assertions passing on nothing the first time it ran: a mutant had committed the previous case's leftovers along with itself, and only a fixture that fails loudly when it cannot apply turned that silent pass into a failure.A name is an edge only a reader infers; a link is one every tool can see. Measured 2026-09-11: this corpus cited its own files 88 times by link and 1,340 times by a backticked name, so Obsidian's graph drew about 6% of the edges the text states, and the link checker — which reads links — validated the same 6%. Converting was mechanical: 640 names in 53 files became links, the checker then resolved every one, and the site build, which fails on a dead link, passed. The always-loaded core kept its names — linked, its 81 would have added 1,785 bytes, about 7% of a file every session pays for, to buy edges its routing table's own check already reads. What it must not touch was the judgement: a released changelog entry is published release notes; a template is copied into projects, where the path does not exist; and
CLAUDE.mdorLATER.mdin prose usually means the project's own file — the site generator had learned that list by breaking twice. In a project the same edge has one more hazard, a declaration. The guard reads a run's task by taking the last id in its**Task**cell, and fed[T-ABC123](tasks/T-ABC123-alpha-slug.md)it returnedT-ABC123-alpha-slug— measured on the function itself, the same day — so the conversion stops at mentions. A live project had 298 links in_ops/and 273 mentions in 171 files that could have been.A guard that is copied is not a guard that is wired, and its presence reads as protection. Measured on a live project 2026-09-16:
_ops/scripts/held the guard, one version behind, and.git/hooks/held nothing but git's own samples — so every gate this methodology describes was, in that repository, a description. What the tree showed underneath is what an ungated project looks like: nine tasks in two incompatible shapes (the template's, and one an agent invented —# T-…: title, fields as a list,Role:where the template saysAssignee, one file carrying two logs), four accepted of which two carry no review evidence, two claiming committed code that is absent from all fifteen commits, a role assigned that exists in neither the team file norroles/, no run records at all, and zero links in_ops/against nine bare ids. The agent that wrote the six divergent tasks diagnosed it correctly and in this corpus's own terms: there was no template on disk it was obliged to open, and no gate that would refuse what it wrote — a rule that states a virtue does not fire. The repair is both halves: a door that writes the shape (new-task.py) and a guard section that refuses a new task departing from it (§23), plus a check that answers the question nobody thought to ask — is the hook wired at all.The advisor doing the work itself is the one bypass no allowlist sees, and "it is not exempt" was the whole of the defence. Measured on the same project the same day: four of its fifteen commits moved files outside
_ops/while nothing under_ops/moved with them — including thirteen files of feature work under one message — and two of its accepted tasks claim committed code that is in no commit at all. Nothing was disobeyed. A gate refuses an action;permissionssaid a gate is a property of the action, not of who performs it, and a sentence has no moment at which it can refuse, so the work simply happened and the ledger did not move. The form is §24, and its threshold is three: a commit that moves the product and not the record warns, and a third in a row is refused naming the two before it. One lone fix is legitimate and common, and a check that refuses those is a check people pass with--no-verify— which is a rule deleting itself. Two was the first threshold and an adversarial lens killed it before it shipped: duringgit commit --amenda pre-commit hook sees the staged change beside a HEAD that is the commit being amended, which is indistinguishable from a second commit in a row — measured 2026-09-18,GIT_REFLOG_ACTIONis empty in the hook for both — so refusing at two would refuse an ordinary amend of one honest fix. One of three can be an amend; three cannot. The record is the whole_ops/tree, not tasks and runs alone, because the fourth of those four commits ischore: opsinist init: the commit that installs the machinery cannot have a task, and under the narrow reading the guard's first act on a fresh project would have been to refuse the commit after its own arrival. The other three touch nothing under_ops/at all, so the widening costs none of them — and the quick path, whose entire shape is a run record and no task, passes on the record it already writes.An uncovered craft leaves exactly one mechanical trace: a name that resolves to nothing. Measured on the same project the same day: two tasks assigned to
Frontend Engineer, a role in neither_ops/roles/— architect, backend_engineer, web_engineer — nor_ops/TEAM.md, apparently read off the Team column standing beside Web Engineer, one of them atreviewwithOwner: unassigned. Design work existed; no design craft was ever hired; the owner's own roster row lists design as their expertise.hiring's fit-check had three exits and none of them was nobody has this craft — so the dispatcher wrote down the nearest-sounding name, which reads as a routing decision and is the absence of one. The form is §25: where a commit WRITES an assignment — a new task or a reassignment — the name must resolve to a role file, a team, a panel or a row of the team file, and the refusal lists who exists.web_engineer.mdanswers toWeb Engineer(normalised in every alphabet, which a[a-z]class would have silently erased for a roster written in the project's own language, and then every unknown name would match every other), a hire in the same commit counts because the roster is read from the index, and an honest blank —unassigned, or a group — passes, because the defect is a name pointing at nobody rather than a gap admitted.A rung named
reviewis not a review — the gate on the edge out of it is, and there was no gate. The stock ladder shippedbuild → review → acceptwithgates: {}for as long as it has existed, so the door consulted no reviewer: a terminal move needed--byand a name that was not the worker's, and nothing anywhere asked that the work had actually been read. Worse, the ladder most projects run on is whatever the type file turned out to be. The type template told them to writebuild → review → acceptas a line of prose, and an inline ladder parses into a pipeline with no gates at all — so a project that writes the file the skill told it to write OVERRIDES the default with an ungated copy of it, once the parser can see it at all (it could not until the same day: [[273]]). Measured 2026-09-16 on a live project: two type files, both inline, both ungated; four accepted tasks, two with no review evidence of any kind. The repair is three-sided, because any one side alone changes nothing: the stock ladder carriesreview_by: non-authoron its terminal edge; the type template's Pipeline section is a yaml block that carries it too; and the guard refuses a ladder the commit ADDS whose terminal stage can be reached with noreview_byon any edge into it, while an existing one is warned about — by the guard on the commit that edits it and by the door on every move. Refusing existing ladders was the tempting version and is the one that gets uninstalled: an upgrade that freezes every in-flight task teaches people--no-verify, which switches off every other section in the file too.The parser normalised the glyph into a local variable, and the one reader that needed it was looking at the original.
parse_pipelinewas repaired once for gates — a lens found thatdraft → reviewwritten with the corpus's own arrow was silently dropped — and the repair normalised each line inside the loop while the inline-ladder search kept reading the untouched body. Sobuild → review → accept, the exact linetemplates/TYPE-template.mdasked every project to write, matched nothing, the whole file parsed toNone, and the task fell back to the stock ladder without a word. Measured 2026-09-17 on a live project: both of its type files, both invisible, and--check-ladderreporting no ladder found about files that plainly declare one. Three things make it the sharpest instance of its class in this corpus: the same defect had already been found and documented ten lines above, in the same function; it fails by finding nothing, which reads exactly like a project that never wrote a ladder; and the fallback it fell into was, until that same day, ungated — so the two defects hid each other, one supplying the silence and the other the permission.A rule that says a file is seeded, never commissioned produces no file at all unless something asks for it.
mappinghas said since it was written that the product map is drawn by the first discovery pass or the corridor read and grows in the task that changes behaviour — and the guard only ever checked a map that already existed, so a project that never made one was never told. Measured 2026-09-16: fifteen commits, nine tasks, a shipped web client and an edge function, no_ops/MAP.md— what does this product do, in what order had no answer in the repository, and every task re-derived it from the code. The repair is a warning, not a refusal, and its escape is the whole design: one honest line in_ops/ARCHITECTURE.mdsaying this product has no flow worth drawing turns it off, exactly as §4 lets a directory be excused. A warning nobody can answer is a warning people stop reading, which is this corpus's own measured failure about checkers that cry wolf ([[261]]).A board is wanted for the same reason a status in the filename is wanted, and only one of them is free.
TODO-,WIP-,DONE-in the name is the first thing everyone proposes; it renames the file on every move, and the id is immutable precisely because links point at the file — so each transition becomes a broken link in every task, run record and thread that cited it, and the state acquires a second home beside the one the door owns.scripts/board.pyanswers the same wish out of the files themselves:_ops/BOARD.md, every id a link,--checkexiting non-zero when the page has drifted from what the tasks now say. Generating it over a live project, 2026-09-16, showed in one screen what nine files had hidden — a status on no rung of that task's own ladder, and six tasks whose assignment was written asRole:, a field the template never declares. Both are marked rather than rendered smooth (⚠,*), which is the whole design rule for a derived view: a view that silently normalises what it reads is how a dialect becomes permanent — and the first draft of this one did exactly that twice, once by reading only the first field on each line (three of nine tasks came out blank, a board reading as a project that had stopped) and once by takingRole:without saying where it came from.A project with no run records does not read as unmeasured — it reads as free. Measured 2026-09-16: nine tasks, fifteen commits, no run records at all, so what did this task cost, what has this release cost so far and what did we spend on work that produced nothing had no answer anywhere, and nothing in the tree said they had none. The rollup —
scripts/cost-report.py, per release · task · model · month — is the form, and its whole design is refusing to roundunknownto zero: where a runtime reported nothing the record saysunknown, the page counts those runs in a not counted column and calls its own totals a floor rather than a measurement. The same refusal covers money: third-party spend lives on another key in another unit, so a run that generated two hundred images describes its thinking in four token numbers and misses the bill entirely — the page sums what the records price and says how many state a quantity nobody has priced yet. Four numbers, never one total, because cache reads are most of the volume and a fraction of the price, and one figure hides the only lever that moves the bill.A skill that is absent does not fail — it loads nothing, and the work merely comes out worse. Measured 2026-09-16: three roles named five skills between them —
frontend-design,modern-web-guidance,vercel-react-best-practicesand two more — while_ops/skills/did not exist and.claude/was empty. All five were installed in the owner's runtime, so every run on that machine was fine and the repository recorded nothing about it; the same clone on another machine attaches five names to nothing, with no error anywhere, which is the failure mode a missing MCP server or a missing system package has and the reasontoolingexists. The repair is the same sentence applied to a fourth kind of thing: what the project needs from the machine is declared — the pool, or a register row naming the runtime that provides it — and the guard's §26 refuses a role whose commit attaches a name resolving to neither. And the row is a link when there is a file to link to, because a backticked name is an edge only a reader infers: the graph, the link checker and/teamall read links, so linking is what makes a role, its skills and the tasks citing them one neighbourhood instead of three islands of identical strings.A mention is a link or the commit does not land — and the rule needed a gate because the door alone left a project with one link and twenty-two bare ids. Measured 2026-09-16:
scripts/link-ids.pyhad existed for a release, reported honestly, and had never been run on that project; nine tasks named an assignee and none of them reached the role. §27 is the gate beside that door: on the lines a commit ADDS under_ops/, an id whose file exists, a backticked internal path, or a person-field naming a role, team or panel must be written as a link, and the refusal names the command that rewrites them. What stays as written is the half that makes it survivable — a## Historyline, a heading, a fence,_ops/runs/,_ops/research/raw/, and the declarations the guard's own readers parse (**Task**,task:), because a linked declaration hands a slug back where an id was expected (fact 265, paid for once already). And the same section keeps the graph honest: a link whose target is absent, an absolute path, or an unencoded space is refused — three shapes that Obsidian, GitHub and the link checker all fail on identically, and that a reader discovers by clicking into nothing.A role the runtime cannot see is a document, and the failure it produces is a project that looks like it only ever had one agent. Measured 2026-09-18: three role files in
_ops/roles/, no.claude/directory at all, and every bar, attached skill and escalation threshold those files carried was read by nobody for the project's whole life — while the advisor did the work itself and nothing anywhere errored. Hiring writes two files: the role, and the wiring the dispatcher reads, which in Claude Code is.claude/agents/<role>.mdneeding onlynameanddescriptionin its frontmatter — no build step and no registration (docs read the same day), which is exactly why forgetting it is easy and silent. §28 refuses the commit that writes a role with no wiring beside it, and §26 — the section that already has the role's skills table open — refuses a role attaching a pool skill that.claude/skills/does not carry; a project operated in another runtime declares its wiring directory once, as theruntime_wiringsetting in_ops/config.md, and the section stands down — a declared setting, because the two earlier shapes of that escape were prose, and prose about agents silenced the check on projects that were wired correctly.A project's dependency belongs to the project, and the default does the opposite.
claude mcp adddefaults to local scope, which writes~/.claude.jsonkeyed by the project's path — and stays there after the directory is deleted;--scope projectwrites.mcp.jsonin the repository instead, and leaves behind only an approval record, clearable withclaude mcp reset-project-choices(docs read 2026-09-18). The same asymmetry runs through skills and agents: committed under.claude/, they arrive with a clone and leave with the repository; installed for the user, they survive it — which is why a project depending on a user-scope skill silently does less on anybody else's machine, the failure §26 exists to refuse. Six characters separate a dependency that travels with the product from one that clutters a machine forever, and they are not the default.A runtime can be retired out from under a shipped integration, and nothing in the repository will notice. Gemini CLI — 100k+ GitHub stars, one of the four runtimes this skill shipped a manifest for — was retired 2026-06-18 and replaced by Antigravity CLI, a different closed-source Go binary invoked as
agy. The two files that existed only for it,gemini-extension.jsonandGEMINI.md, went on being shipped, swept for version parity by this repository's own preflight, and documented as a live install route. The check that exists is the one that reads the machine, not the tree:scripts/find-installs.shfound the dead runtime's install directory still sitting in~/.gemini/extensions/— twice, on 2026-09-18 — which is why that row now says remove it rather than update it. The successor was measured rather than assumed:agy plugin validate .on 1.2.5 answers ok, 21 skills processed andhooks: skipped (not found), so the skills load and the audit gate does not reach it — and the filenameGEMINI.mdoutlives the product, becauseagy's own help still names it, besideAGENTS.md, as a path it reads for rules.The file-shaped memory this system is a relative of is measurably worse at recall than a search index, and measurably better at saying it does not know. Read 2026-09-18, from a taxonomy of agent-memory architectures with benchmark runs behind each: a model curating markdown and recalling it by grep scored 44.9% where an embedded store of atomic facts scored 73.6% on the same questions, and cost 287k model tokens per question against 19k — because curation is a reasoning act, priced at roughly 246k tokens and 35 minutes per history against five minutes to embed. The one category it won was abstention, 88.9% against 77.8%, and the author's explanation is the sentence this whole corpus is built on: "retrieval almost always surfaces something plausible enough to tempt an answer, while a curation-limited store often has nothing to offer and the model correctly says so." The measured arm is a relative and not this system: it recalled by grep, where this one is read by path and by link, and whether that closes any of the gap is a question nobody has run. So the number is carried as a direction rather than as a score: a record read by path and link is a record that can be empty in an honest way, the price of that is paid every time somebody has to write it down, and the thing it is known to do badly is finding one fact scattered across a long history.
A skill is code with an implicit trust grant, and a quarter of the ones people publish are unsafe. NVIDIA's SkillSpector — the scanner behind its Verified Skills pipeline, which scans, evaluates and signs before publication — reports that in a 31,132-skill analysed subset, 26.1% contain vulnerabilities and 5.2% show likely malicious intent (read 2026-09-18). That is the measurement under every screening rule this system has: an imported skill is untrusted code and untrusted instructions, screened with a named command before it is attached, re-screened on every update against the version that was vetted, and recorded with source, version, date and who approved. And the rule that says imported is read by everybody as all, which is how a project's own skills go unscanned: a file you wrote cannot be malicious and can easily be over-granted, injectable or leaky. Measured here the same day, on the first scan this corpus had ever run on itself — 21 skills and the sibling's 19, three findings, none of them a true positive for malice: a skill whose documented job is upgrading skills tripped Rogue Agent / Self-Modification; a skill that points at a sibling file tripped analysis-evasion, which is a fact about the scan's own coverage rather than about the file; and a line reading "never refuse a doable action over the wrong seat" tripped anti-refusal. That third one earned its keep: the sentence was about which seat does the work, and a model reading it out of context could take it for something else, so it now says so — the seat is not a reason to decline, and gates are untouched by this. The scan then passed that line; the other two stood as what they were, and the self-modification one went on tripping until a later round reworded the skill to say what it upgrades. A scanner produces evidence, not verdicts — and the evidence was right. The count in this line was wrong for a day: it said two, because the sibling's second finding was never re-read before it was written down, and a contradiction lens re-ran the named command.
A dependency arrives with a reason and leaves with none, because nobody wrote the condition down. The commit that adds one is already refused unless
_ops/DECISIONS.mdsays what it replaces and what was rejected — the why is a gate. The other end of that sentence was missing: a register row now carriesGone when, the observable condition that retires it (when the platform ships it · when the free tier stops covering us · when the feature it serves is cut), because when we don't need it is not a condition anybody can observe, and a dependency with no removal condition never leaves. And a row carries what the service itself SHIPS — an MCP server, a CLI, an SDK, an agent skill — wherechecked <date> · none foundis a complete answer and an empty cell is not, since an empty cell cannot be told apart from nobody having looked. Measured on a live project 2026-09-16: an auth service, a database service, a model key and a hosting provider all in use and no_ops/TOOLING.mdat all, so nothing ever asked whether any of them had an API, a CLI or an MCP — the guard now warns once, on any project that declares dependencies in a manifest and has no register.A gate that reads prose can be satisfied by rewording, which is the one thing an outward gate must not be. Both copies of this system's publish gate matched their verbs anywhere in the command string, so a sentence about publishing — a comment being written into a file — was refused as if it were the act: measured 2026-09-18, twice in one session, the second time on the comment explaining the repair. The only route past a gate that reads prose is to change the prose, and "a gate satisfied by vocabulary teaches people to sprinkle words" is this corpus's own rule about exactly that. A command starts a command; a word after another word is prose — so the verb is anchored at a command position (the beginning, a newline, after
;&&|||, inside a subshell), and a quote counts as one only after something that runs a shell, because treating every quote as a command start refuses a search for the phrase, and a search is a read. Comparing the two copies found a hole in each: one had no anchor at all, the other was blind to a newline, a pipe, a subshell and a wrapper's quoted argument, and its lookahead demanded whitespace after the verb — so a subshell's closing paren made it silent, which no test had ever tried. Two copies of one rule diverge in both directions at once, and only reading them against each other shows it.A scanner can report successful about a skill it never read. Thirteen skill descriptions across this system's two repositories held a plain value with
:inside it — legal to a lenient reader, a mapping inside a mapping to a strict one — and SkillSpector's parser rejected those manifests in the pre-tag scan of 2026-09-24 while its printed summary said the scan succeeded with no findings. The only trace was amanifest_parse_errorin each skill'sanalysis_completeness, visible in the JSON and nowhere else. Two repairs, one for each half: a strict frontmatter check refuses the shape on the commit, and the scan before a tag is read as JSON, wheregrep -c manifest_parse_errormust print0— because a clean summary over a skill that was skipped is the same silence as a clean skill.A gate tested against what its author expects bash to do passes exactly the cases its author imagined. In the release that repaired this system's publish gate, the part that blanks heredoc bodies was out-guessed five times by commands where the author's expectation and bash disagreed — each found by a lens reading the code, none by the suite, whose every case stated the verdict its author expected. So the oracle became bash:
scripts/test-gate-vs-bash.shruns each command in/bin/bashagainst stubs, reads published from what the stubs were asked to do, and requires the gate to agree. And it cannot publish, four ways over — only stubs and harmless tools onPATH, every stub checked before each run, the network denied, and any real outward tool refused execution by any path — measured necessary on 2026-09-24, when a lens testing the gate with a stubgitfound none, fell through to the real one, and pushed eighteen commits to a public branch.A release note's counts are claims, and a claim nobody measures drifts in the direction of the work that came late. 0.2.19's Trio line said diagrams 8 · situations 21 · facts 262–277, and the range from the tag before it added 10 · 24 · 262–282; its sibling's said situations 5 over a range that added 7. Twenty-six lens rounds had read that release, each over one repair's diff, so none of them ever held the entry against the release as a whole — the owner found it by asking.
scripts/check-trio.pynow reads the Trio line and counts the range; run over the five releases before 0.2.19 here, it confirmed two, found two lines naming their facts in words it could not read, and one entry with no Trio line at all; next door, the two releases before 0.4.18 matched (2026-09-25).Linking a name forces reading the thing it names. The owner's rule of 2026-09-25 — every project on the shelf carries a link — met a rough count of about ninety-six bold names without one, and most of them were licences and emphasis rather than projects; the check that replaced the count reads the head of each shelf entry and found forty-five real names here and forty-three next door, SwiftUI, Vitest and CodeQL among them. Finding the link for one of them corrected its row: PACT had been listed as the callable layer of the agent web, and its source says it is Private Access Control Tokens — a site that knows the human vouching for an agent anonymously — which is a different thing entirely.
A star count on a young repository is not evidence, and a push date is not a commit date. Reading two hundred repositories on 2026-09-25 met a security-audit skill at 21k stars on 76 watchers, eight days after 7.2k, a code-review tool that went from 32k to 40.8k in the same eight days, and an agent-memory project at 27k stars on 91 watchers in five and a half months — and a server framework whose page shows a 2026 push while its last real commit is from 2022. What was read instead: watchers, forks, contributors and the commit log. A description can contradict its own licence too — one avatar project's README says truly open-source over a licence that turns commercial past a thousand monthly users.
Several free scholarly APIs answer a failure with HTTP 200, so a status code says the request arrived and nothing about whether it was answered. Named in the
paper-lookupskill of K-Dense's scientific-agent-skills (MIT, read 2026-09-25, not re-measured here): PMC returns a well-formed article with no body when the publisher forbids redistribution; arXiv returns one entry titledErrorfor a malformed parameter and silently widens an unknown field to all fields; Europe PMC puts its error code inside a 200 body; bioRxiv accepts an out-of-step cursor and returns the wrong thirty records; Figshare's search ignores its query; and OpenCitations answers a DOI that does not exist with a count of zero — a plausible fact about a real paper, and an ordinary answer about a fake one.A citation that resolves is not a citation that supports. Checking that a source exists, and that it was read beside its neighbours, says nothing about whether the sentence carrying it says what the source says — which is the claim-level check academic-research-skills builds into its pipeline, classifying each claim as supported, overstated, unsupported or unverifiable against the passage it cites. Its authors report (read 2026-09-25, not re-measured) that an independent audit after publication found 21 of 68 real issues that three rounds of integrity checks had missed — the same lesson as a lens round that reports clean, measured in another field. The method is taken here and none of the text, because that pack is licensed CC BY-NC.
A pipe inside a search pattern is a character, and a gate that reads it as a pipe refuses the owner's own search. On 2026-09-25 this system's publish gate refused
grep -n -i "outward\|publish gate\|…" PLAYBOOKS.md— the|of the regular expression read as a command separator and the verb after it as the start of a command — and a commit message holding a;or a newline before the verb was refused the same way. The repair had to be narrow, because the same misreading was catching real acts by accident:echo "a; …" | bash, an interpreter's-cprogram and a file written then run byshall carried their verb behind a separator inside quotes. So a quote is read as data only where a reading command holds it — grep, rg, echo, printf, a git message — and nothing in the command can run text; everywhere else the old, loud reading stands. Held against bash itself inscripts/test-gate-vs-bash.sh, where the new cases pass and two mutants — the runner check removed, a quoted shell name not read as a shell — each open a hole. The same afternoon's reading foundtimeout 60 …walking past both gates, because the wrapper list did not name it;timeoutanddoasare wrappers now. And the first lens over the repair found its own hole: the list of shells that run text named five, so a reader's quote piped intocshortcsh— both shipped with macOS — published through the new exception. Sixteen shells are named now —csh,tcshandkshheld against bash itself — and a wrapper in front of a reader (nice grep …) no longer hides the reader.