Skip to content

Compose vision with gates, and cover what a workcell needs to keep running - #5

Open
di-omics wants to merge 2 commits into
mainfrom
feat/coverage-durability-teaching-feedback
Open

Compose vision with gates, and cover what a workcell needs to keep running#5
di-omics wants to merge 2 commits into
mainfrom
feat/coverage-durability-teaching-feedback

Conversation

@di-omics

Copy link
Copy Markdown
Owner

Four layers for the part of an autonomous lab that begins once more than one instrument is involved.

coverage.py -- the composition, and the reason for the rest

vision knows what a camera can and can never see. qc knows which gates exist and whether they fire. recovery knows which failures destroy material. Nothing joined them, so nothing could answer the question a lab actually asks: for every failure that destroys material, is there anything at all that would catch it?

On the reference protocol: 14 failure modes, 0 covered, 9 destructive. They do not split into one problem:

6 a camera would catch checks declared, undeployable. bead_pellet_aspirated is here -- the failure recovery already calls the worst silent one
1 invisible, gate already reads it enzyme_activity_lost sits behind an unsatisfiable gate because the reader is broken. Repair the instrument
7 no camera reaches at any capability mandatory_gates(). A better model buys nothing. They need an assay the protocol does not have

sota_lift() returns both lists, because a report showing only what a capability lifts is a purchase justification.

The other three

durability tracks entitlement, not prediction: whether a planned campaign crosses a service or calibration boundary mid-run. No MTBF, because that needs population data nobody has.

teaching holds that a demonstration is data, not authority. A scientist doing something twice is two observations with a spread. An envelope refuses a tolerance from n=1, and a machine with one good run reports as indistinguishable from unmeasured.

feedback refuses any loop whose sensor sits downstream of its actuator: a measurement taken after the material is consumed is a post-mortem wearing the costume of a control loop.

The audit earned its keep

Three adversarial lenses found the class of defect these modules exist to refuse, committed by them: a gate reading an undeclared measurement counting as coverage; a duplicate gate row silencing an unsatisfiable one because the lookup returned the first match; a workcell declaring no instruments reporting as clean; a NaN accrual read as a measurement; a campaign landing exactly on a boundary reported as not crossing it. All closed with regression tests.

156 new tests. Recreated after the PR history was reset; the branch is unchanged.

di-omics added 2 commits July 29, 2026 10:39
…nning

Four layers for the part of an autonomous lab that starts once more than one instrument is
involved: whether anything would catch a failure, whether the instruments are still
entitled to be trusted, whether an expert has taught the operation, and whether a control
loop can close.

coverage is the composition and the reason the other three are worth having. vision knows
what a camera can and can never see, qc knows which gates exist and whether they fire, and
recovery knows which failures destroy material. Nothing joined them, so nothing could
answer the question a lab actually asks: for every failure that destroys material, is there
anything at all that would catch it?

On the reference protocol the answer is 14 failure modes, none covered, 9 of them
destructive. The useful part is that they do not split into one problem. Six are visible
and their checks are declared and undeployable -- a CV project with a known payoff, and
bead_pellet_aspirated is among them. One is invisible but already sits behind a declared
gate that cannot fire because the reader is broken, so no camera is involved and a repair
closes it. Seven are invisible with no assay reading the quantity they change, and no
capability upgrade moves them at any price. Confusing those three is how a CV budget gets
spent against a problem no model solves. sota_lift therefore returns both lists, because a
report showing only what a capability lifts is a purchase justification.

Two things refused as coverage: a vision check that exists but whose requirements are unmet,
and a gate that exists but cannot be evaluated. Counting either reports a lab as covered
while material is quietly destroyed.

durability tracks entitlement rather than predicting failure. It computes whether a planned
campaign crosses a service or calibration boundary mid-run, because a plate that started
before an expiry and finished after it has an ambiguous provenance and nothing downstream
repairs that. No MTBF and no remaining-life estimate: that needs population reliability
data this package does not have, and the invented figure becomes a specification.

teaching models the transfer. A demonstration is data, not authority -- a scientist doing
something twice is two observations with a spread, and the spread is the information. An
envelope refuses a tolerance from one demonstration and a machine with one good run reports
as indistinguishable from unmeasured. The operations with no envelope are the real backlog
of an automation programme and demonstration_queue ranks them the way unlocks() ranks
decoding work.

feedback asks whether a loop closes, with latency as the load-bearing check: a sensor
downstream of its own actuator is a post-mortem wearing the costume of a control loop. No
gain, no settling time -- that needs a plant model and measured response data. What it does
report is how many plates are already committed between sensor and actuator.

Each module was built, adversarially audited on three lenses, and fixed. Includes a fix for
attainment() naming the untaught operation in its own refusal, which is the common case and
was reading "no expert has demonstrated 'unknown'".

156 new tests, 284 total.
Three audit lenses ran against each of the four modules -- one hunting defaults that read as
a PASS when they are really a SKIP, one checking that no fact is recomputed where a sibling
module already owns it, and one actively trying to extract a flattering answer. Between them
they found the same class of defect this package exists to refuse, committed by the modules
written to refuse it.

The pattern repeats across all four. A gate reading a measurement nobody declared counted as
coverage. A demand was met by a measurement set that says nothing. A duplicate gate row
silenced an unsatisfiable one because the lookup returned the first match, which also made
the report depend on row order. A workcell declaring no instrument at all reported as a clean
lab. A NaN accrual was read as a measurement. A negative accrual minted budget that was never
earned. A campaign landing exactly on a service boundary was reported as not crossing it. A
coverage report holding nothing destructive reported as complete.

Two are worth naming separately because they are cross-module rather than local. A recovery
report built against a different gate report was accepted and silently mixed two workcells'
worth of evidence; it is now refused. And a gate path this module had already refused was
being republished as a residual detection path, so a failure this layer called uncovered
appeared one line later as watched by the thing that could not watch it.

Every fix carries a regression test that fails before it and passes after. No existing test
was weakened to make anything pass.

63 new tests, 347 total. ruff clean.
@di-omics
di-omics force-pushed the feat/coverage-durability-teaching-feedback branch from d531723 to 3330cda Compare July 29, 2026 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant