feat: cleaning 10/12 — the call runner: GPU slots, one trouble clock, the breaker and the canary #169

Merged
bjoern merged 35 commits from feat/cleaning-call-runner into main 2026-10-05 20:53:04 +02:00
Member

This is slice 10 of Phase 5 in PROJECT_PLAN.md: the call runner from ADR 0027's "The server" section. It sits between the stage and slice 9's adapter, and owns every job on the cleaning server: the GPU slots, the deadlines, the one 20-minute trouble clock, the breaker, the canary and the raw cache. Nothing calls it yet. The clean tool arrives in slice 11 and the stage in slice 8, so a saved server address still changes no stage.

What's in

Domain and EF: CleaningCall (one row per server job), CleaningOutput (one row per candidate, with an indexed cache key) and a single CleaningServerState row (epoch, canary hashes, fingerprint, breaker), in one migration, AddCleaningCallRunner.

  • A page's calls are deleted with the page. The execution and invocation are plain ids with no foreign key.
  • Canary jobs are rows with no page, always charged to the stage.

Store and files:

  • EfCleaningCallStore sums GPU seconds per page and per run, split by who pays.
  • Call files go under the chapter's clean/<pageId>/calls/<callId>/ (window, raws, call.json) and are written atomically.

Pixel digest: a new IPixelDigest port, with SkiaPixelDigest.

  • An 8-bit grey PNG is read as its own levels; anything else goes through the canonical decode.
  • An image whose data ends early does not digest, in either mode, as in Pillow.
  • It is frozen against Pillow by a committed generator, Raster/oracle/gen_digest_oracle.py.

CleaningCallRunner, a singleton modelled on RunEngine:

  • The in-flight gate. "GPU jobs in flight" is re-read on every acquire, first come first served, with one slot while the backend is half up. A trip answers every waiting call at once.

  • Dedupe and the raw cache.

    • Identical calls in flight share one job, and a failure on a shared job counts once against the call.
    • Each output has its own cache key; labels are keyed as they are sent.
    • Identity-unknown outputs serve only their own call.
    • A cached raw is read beside the call that made it, and a raw whose file is gone is run again.
    • Missing candidates are run again alone, at their replay seeds.
  • Restarts. Job ids are stored before the first poll. CleaningCallRunnerBootstrap resumes polling at boot, before RunEngineBootstrap, and never resubmits. A restart inside a running stint keeps the whole stint.

  • Deadlines and classification, on TimeProvider:

    • 5 minutes of summed running time, and 20 minutes in total from the first running poll;
    • every error code and rejected-submission shape classified by one pure function;
    • an unknown retryable code is resent at most its max_retries.
  • The one 20-minute trouble clock. It counts outage polls, retryable failures and deadline cancels. It also counts every wait on a server that does not answer: the health check before a submit, the submit itself, a job the server forgot, the canary's health check, and an output fetch. Past 20 minutes the breaker trips.

  • A hung backend. The runner sends DELETE until the job is final, holding the slot. It charges the stage and fails the call once; a second hang on the same call trips the breaker. server_stopped is resent once.

  • The breaker. The stop classes trip it at once. Its state and reason persist on the server-state row, and Resume cleaning or a boot clears it.

  • The canary. Three shapes on drawn canvases (L bubble, L floating n = 3, RGB colour floating), committed with their generator. It runs:

    • before the first job after a boot;
    • after a fingerprint change, after a per-job identity mismatch (a failed job's too), and after the breaker clears.

    One runs at a time, and a request raised while one runs is not lost. Its result records or advances the epoch. BeforeFirstJobOfRun is the hook slice 8 calls at each cleaning run's first job.

  • The GPU wait on the run monitor's pulse: queued at #n, slot #n, or backend down since a time, cleared as soon as it stops being true.

Page operations: page delete, bulk delete, move, bulk move and chapter delete are refused while the runner holds a job for the page.

UI:

  • a Pixel pass card on Settings → Agents, with "GPU jobs in flight" (1 or 2, default 2);
  • the Cleaning server card gains the canary's epoch, the breaker's state and reason, the last halt, and Resume cleaning;
  • the run monitor's pulse shows the GPU wait.

Docs:

  • ADR 0021 is amended (2026-10-05) for the server's v0.5.0 build ids; see the honest notes.
  • ADR 0027 gains one clause, on a /healthz read that names no backend.
  • AGENTS.md's "Not seeded" sentence names the GPU jobs in flight and the untouched runner state.

Tests

2,262 green and 2 skipped, against 1,965 on main (+297):

Project Count Change
Domain 144 +12
UseCases 925 +246
Integration 902 +27
BlazorAdapter 291 +12

The skips are opt-in: this slice's live smoke test, and main's corpus test. Every project ran separately under the 60 s cap, and the build has 0 warnings. What they pin:

  • The lab's a3953f7 simulation traces, replayed from traces.json, which a committed generator makes:
    • the job clock reproduces the record's running sums within 0.05 s, and the B2 deadline at 360.98 s;
    • the half-up and recheck rule matches every recorded poll;
    • five traces run through the runner against a scripted server.
  • Every way to the breaker: each silent-server wait is driven past 20 minutes; the stop classes; a canary submit the server rejects, charged to the stage; a hang twice.
  • The canary: its failures and refusal, one run at a time, its back-off on a silent server, a request raised while one runs, and a mismatch on a failed job.
  • Restarts: polling resumes and never resubmits; the running time and an open stint survive.
  • The gate: each waiter's place in line, a trip and a boot freeing it, a cancel that ends on its own as done or error, and one probe while half-up.
  • Identity: a release, a build past a release, an older server's 12-hex id, a job naming another build, a dirty build and an overridden one.
  • Mutation. Three independent review rounds ran about 350 mutants over the whole diff. Every surviving arm is now pinned by a test that fails without it, or deleted where nothing could observe it; eight such arms were deleted.

Browser-verified

I ran a fresh seeded world with the fake server on its own port, driven with Playwright. All 20 checks passed, and I looked at the screenshots:

  • Pixel pass: labelled "GPU jobs in flight", with exactly Default — 2, 1 job and 2 jobs. Picking 1 job stores 1 (read back from SQLite) and survives a reload; picking the default removes the row.
  • Cleaning server, running: the address typed key by key saves. The card reads Epoch 0, "no canary has run yet · runs before the next job" and "Running normally", with no Resume.
  • Halted (the state row written as the runner writes it): the reason shows; the card reads "Halted since 2 minutes ago" and "Epoch 1 passed 5 minutes ago"; no last-halt row shows.
  • Resume cleaning clears the halt, back to "Running normally". The last halt keeps its reason with "cleared just now", the row reads cleared, and a reload keeps it so.
  • The migration: the host's database has the new RunningSince column.

The live smoke test (ORIHON_CLEANING_SMOKE_SERVER) passed against your server, v0.5.0, three times today, run by the fix agents and a reviewer; I did not rerun it.

  • The canary ran with 7 outputs and was confirmed at epoch 0.
  • A bubble call (n = 1) and a floating call (n = 3) came back with every output identity-confirmed.
  • The same bubble call again was served from the raw cache.

Honest notes

  • The build-identity rule is my call; please overturn it if you disagree. Your server reports its build as v0.5.0. Since v0.5.0 the id is git describe, so the old "12-hex id" rule confirmed nothing on it: the raw cache would never serve, and the mismatch trigger would never fire.

    • A build is now known when /healthz reads build.dirty as false.
    • A job's run.build must still equal build.id.
    • A dirty, overridden or unknown build stays unknown.

    It covers older servers' 12-hex ids unchanged. ADR 0021's amendment says why, from the server's own app/buildinfo.py.

  • A /healthz that names no backend runs no canary. v0.5.0 reads backend_identity fresh, and it is null while ComfyUI is slow to answer. It compares as the backend the last canary confirmed.

  • Nothing calls the runner yet. Slices 8 and 11 must:

    • call BeforeFirstJobOfRun at each cleaning run's first job;
    • check HaltReason in the executor;
    • turn CleaningCallHalted and CleaningCallFailed into ADR 0027's halt and fail-once;
    • requeue halted rows on Resume.
  • Page operations don't carry call files yet (slice 7). A moved page's calls stay in the old chapter, and a deleted page's stay on disk until its chapter or project is deleted.

  • My choices where the ADR gives no number: back-off 2, 4, 8, 16, then 30 s; a 1 s poll interval; and a /healthz read before every submit and on every poll.

  • The cards read on visit and on Check again; nothing pushes the runner's state live.

  • Cosmetic, on slice 9's card: a dirty build reads "v0.5.0-dirty (dirty)". The fake server still reports decafbad0001, which reads as known under the new rule.

  • An unrelated flake: AnnotationRunTests.A_hand_reprocess_still_reaches_the_transcriber_in_its_own_words failed once in about 30 runs under load. It waits on real time in code this branch does not touch.

  • Merge. The branch is rebased onto main after #167 and #168. The one conflict, in DependencyInjection.cs, keeps both slices' registrations, and the rebased tree equals a plain merge's.

🤖 Generated with Claude Code

This is slice 10 of Phase 5 in `PROJECT_PLAN.md`: the call runner from ADR 0027's "The server" section. It sits between the stage and slice 9's adapter, and owns every job on the cleaning server: the GPU slots, the deadlines, the one 20-minute trouble clock, the breaker, the canary and the raw cache. Nothing calls it yet. The `clean` tool arrives in slice 11 and the stage in slice 8, so a saved server address still changes no stage. ## What's in **Domain and EF:** `CleaningCall` (one row per server job), `CleaningOutput` (one row per candidate, with an indexed cache key) and a single `CleaningServerState` row (epoch, canary hashes, fingerprint, breaker), in one migration, `AddCleaningCallRunner`. - A page's calls are deleted with the page. The execution and invocation are plain ids with no foreign key. - Canary jobs are rows with no page, always charged to the stage. **Store and files:** - `EfCleaningCallStore` sums GPU seconds per page and per run, split by who pays. - Call files go under the chapter's `clean/<pageId>/calls/<callId>/` (window, raws, `call.json`) and are written atomically. **Pixel digest:** a new `IPixelDigest` port, with `SkiaPixelDigest`. - An 8-bit grey PNG is read as its own levels; anything else goes through the canonical decode. - An image whose data ends early does not digest, in either mode, as in Pillow. - It is frozen against Pillow by a committed generator, `Raster/oracle/gen_digest_oracle.py`. **`CleaningCallRunner`**, a singleton modelled on `RunEngine`: - **The in-flight gate.** "GPU jobs in flight" is re-read on every acquire, first come first served, with one slot while the backend is half up. A trip answers every waiting call at once. - **Dedupe and the raw cache.** - Identical calls in flight share one job, and a failure on a shared job counts once against the call. - Each output has its own cache key; labels are keyed as they are sent. - Identity-unknown outputs serve only their own call. - A cached raw is read beside the call that made it, and a raw whose file is gone is run again. - Missing candidates are run again alone, at their replay seeds. - **Restarts.** Job ids are stored before the first poll. `CleaningCallRunnerBootstrap` resumes polling at boot, before `RunEngineBootstrap`, and never resubmits. A restart inside a running stint keeps the whole stint. - **Deadlines and classification**, on `TimeProvider`: - 5 minutes of summed running time, and 20 minutes in total from the first running poll; - every error code and rejected-submission shape classified by one pure function; - an unknown retryable code is resent at most its `max_retries`. - **The one 20-minute trouble clock.** It counts outage polls, retryable failures and deadline cancels. It also counts every wait on a server that does not answer: the health check before a submit, the submit itself, a job the server forgot, the canary's health check, and an output fetch. Past 20 minutes the breaker trips. - **A hung backend.** The runner sends DELETE until the job is final, holding the slot. It charges the stage and fails the call once; a second hang on the same call trips the breaker. `server_stopped` is resent once. - **The breaker.** The stop classes trip it at once. Its state and reason persist on the server-state row, and Resume cleaning or a boot clears it. - **The canary.** Three shapes on drawn canvases (L bubble, L floating n = 3, RGB colour floating), committed with their generator. It runs: - before the first job after a boot; - after a fingerprint change, after a per-job identity mismatch (a failed job's too), and after the breaker clears. One runs at a time, and a request raised while one runs is not lost. Its result records or advances the epoch. `BeforeFirstJobOfRun` is the hook slice 8 calls at each cleaning run's first job. - **The GPU wait** on the run monitor's pulse: queued at #n, slot #n, or backend down since a time, cleared as soon as it stops being true. **Page operations:** page delete, bulk delete, move, bulk move and chapter delete are refused while the runner holds a job for the page. **UI:** - a **Pixel pass** card on Settings → Agents, with "GPU jobs in flight" (1 or 2, default 2); - the **Cleaning server** card gains the canary's epoch, the breaker's state and reason, the last halt, and **Resume cleaning**; - the run monitor's pulse shows the GPU wait. **Docs:** - ADR 0021 is amended (2026-10-05) for the server's v0.5.0 build ids; see the honest notes. - ADR 0027 gains one clause, on a `/healthz` read that names no backend. - AGENTS.md's "Not seeded" sentence names the GPU jobs in flight and the untouched runner state. ## Tests 2,262 green and 2 skipped, against 1,965 on main (+297): | Project | Count | Change | |---|---|---| | Domain | 144 | +12 | | UseCases | 925 | +246 | | Integration | 902 | +27 | | BlazorAdapter | 291 | +12 | The skips are opt-in: this slice's live smoke test, and main's corpus test. Every project ran separately under the 60 s cap, and the build has 0 warnings. What they pin: - **The lab's a3953f7 simulation traces**, replayed from `traces.json`, which a committed generator makes: - the job clock reproduces the record's running sums within 0.05 s, and the B2 deadline at 360.98 s; - the half-up and recheck rule matches every recorded poll; - five traces run through the runner against a scripted server. - **Every way to the breaker:** each silent-server wait is driven past 20 minutes; the stop classes; a canary submit the server rejects, charged to the stage; a hang twice. - **The canary:** its failures and refusal, one run at a time, its back-off on a silent server, a request raised while one runs, and a mismatch on a failed job. - **Restarts:** polling resumes and never resubmits; the running time and an open stint survive. - **The gate:** each waiter's place in line, a trip and a boot freeing it, a cancel that ends on its own as done or error, and one probe while half-up. - **Identity:** a release, a build past a release, an older server's 12-hex id, a job naming another build, a dirty build and an overridden one. - **Mutation.** Three independent review rounds ran about 350 mutants over the whole diff. Every surviving arm is now pinned by a test that fails without it, or deleted where nothing could observe it; eight such arms were deleted. ## Browser-verified I ran a fresh seeded world with the fake server on its own port, driven with Playwright. All 20 checks passed, and I looked at the screenshots: - **Pixel pass:** labelled "GPU jobs in flight", with exactly Default — 2, 1 job and 2 jobs. Picking 1 job stores `1` (read back from SQLite) and survives a reload; picking the default removes the row. - **Cleaning server, running:** the address typed key by key saves. The card reads Epoch 0, "no canary has run yet · runs before the next job" and "Running normally", with no Resume. - **Halted** (the state row written as the runner writes it): the reason shows; the card reads "Halted since 2 minutes ago" and "Epoch 1 passed 5 minutes ago"; no last-halt row shows. - **Resume cleaning** clears the halt, back to "Running normally". The last halt keeps its reason with "cleared just now", the row reads cleared, and a reload keeps it so. - **The migration:** the host's database has the new `RunningSince` column. **The live smoke test** (`ORIHON_CLEANING_SMOKE_SERVER`) passed against your server, v0.5.0, three times today, run by the fix agents and a reviewer; I did not rerun it. - The canary ran with 7 outputs and was confirmed at epoch 0. - A bubble call (n = 1) and a floating call (n = 3) came back with every output identity-confirmed. - The same bubble call again was served from the raw cache. ## Honest notes - **The build-identity rule is my call; please overturn it if you disagree.** Your server reports its build as `v0.5.0`. Since v0.5.0 the id is `git describe`, so the old "12-hex id" rule confirmed nothing on it: the raw cache would never serve, and the mismatch trigger would never fire. - A build is now known when `/healthz` reads `build.dirty` as false. - A job's `run.build` must still equal `build.id`. - A dirty, overridden or unknown build stays unknown. It covers older servers' 12-hex ids unchanged. ADR 0021's amendment says why, from the server's own `app/buildinfo.py`. - **A `/healthz` that names no backend runs no canary.** v0.5.0 reads `backend_identity` fresh, and it is null while ComfyUI is slow to answer. It compares as the backend the last canary confirmed. - **Nothing calls the runner yet.** Slices 8 and 11 must: - call `BeforeFirstJobOfRun` at each cleaning run's first job; - check `HaltReason` in the executor; - turn `CleaningCallHalted` and `CleaningCallFailed` into ADR 0027's halt and fail-once; - requeue halted rows on Resume. - **Page operations don't carry call files yet** (slice 7). A moved page's calls stay in the old chapter, and a deleted page's stay on disk until its chapter or project is deleted. - **My choices where the ADR gives no number:** back-off 2, 4, 8, 16, then 30 s; a 1 s poll interval; and a `/healthz` read before every submit and on every poll. - **The cards read on visit and on Check again;** nothing pushes the runner's state live. - **Cosmetic, on slice 9's card:** a dirty build reads "v0.5.0-dirty (dirty)". The fake server still reports `decafbad0001`, which reads as known under the new rule. - **An unrelated flake:** `AnnotationRunTests.A_hand_reprocess_still_reaches_the_transcriber_in_its_own_words` failed once in about 30 runs under load. It waits on real time in code this branch does not touch. - **Merge.** The branch is rebased onto main after #167 and #168. The one conflict, in `DependencyInjection.cs`, keeps both slices' registrations, and the rebased tree equals a plain merge's. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
One row per server job, one per returned candidate with an indexed cache key, and the cleaning
server's one state row: the epoch, the canary's reference hashes, the identity it was confirmed
on, and the breaker with its reason. A page's calls go with the page; the execution and the
invocation are plain ids, so the GPU accounting outlives a cancelled run. The store sums GPU
seconds per page and per run, split by who pays.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A call's window, raws and call.json live under the chapter's clean/<pageId>/calls/<callId>/,
named by id and written whole. The raw cache and the canary compare decoded pixels, never file
bytes: an 8-bit grey PNG as its own levels, anything else through the canonical decode, frozen
against Pillow on the canary's canvases. Those three canvases are drawn by a committed script
and ship with the assembly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 or 2, default 2, stored like the fan-out: absent is the default, a row out of range reads as no
choice, and clearing removes the row. The settings read carries the choice and the effective
number.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CleaningCallRunner is a singleton modelled on the run engine. A call waits for a GPU slot (the
in-flight setting, re-read on every acquire; one while the backend is half up), for the canary
when one is due, and for a job already in flight under its key. Outputs are cached per replay
seed under the epoch; an output whose identity the per-job check cannot confirm serves its own
call only. Job ids are persisted before polling, and a hosted service registered before the run
engine's takes them up at boot, so a requeued call awaits its job instead of resubmitting.

Failures are sorted by one pure function. Retryable ones are waited out with back-off on one
20-minute trouble clock; server_stopped is resent once; a run_timeout, an out-of-memory or a
hang fails the call once and halts on a repeat; the stop classes, a rejected submission and any
input note but the allowed one trip the breaker, which persists and clears on Resume or a boot.
A job past its running or total deadline is judged by /healthz: an outage or a half-up backend
is waited out, a hung one deleted until final with its slot held. GPU seconds are timings.total_s,
charged to the stage for the server's own trouble. The canary's three shapes run before the
first job after a boot, a resume, a /healthz fingerprint change or an identity mismatch, and
before the first job of each cleaning run when the stage asks. The deadlines and the
classification are replayed on the cleaning lab's a3953f7 simulation traces, and an opt-in
smoke test runs a bubble and a floating call on a live server.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Page delete and move, their bulk forms and chapter delete are refused while the call runner
holds a job for a page they touch: from the call until the server reads the job final, a cancel
still landing included. The runner resolves a call's directory when it writes, so a move that
slips past the check still finds its files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Settings → Agents gains a Pixel pass card with GPU jobs in flight: the default, 1 or 2, saved on
pick. The Cleaning server card shows the canary's epoch, whether a canary is due, and the
breaker: running, waiting out trouble, probing a half-up backend, or halted with its reason and
Resume cleaning. Check again reads the runner too. The run monitor's pulse says why a cleaning
call is quiet: checking the server, waiting for a GPU slot, queued at #n, or backend down since.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two lists, one under the other, now share a label column, so their values read in one line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No GPU jobs in flight are chosen and no call, canary or halt is recorded, so the server state
reads epoch 0 with no canary until something calls the runner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pages that go while a call waits for a slot or as its job is submitted, a row gone under a kept
page, a fetch or a DELETE the server does not answer, a job forgotten mid-cancel, a halted job's
record, a freed slot starting the next job at once, an outage that heals under a deadline, the
job clock across a restart, a loaded job's slot, and what a resume sets back. The store's add
now has one path for a vanished page, the foreign key's own refusal; the cache lookup, the gate
and the in-flight save lose arms no test could tell from their absence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A server silent as the canary starts is waited out on the clock; a canary job that fails once
fails the call and leaves the canary due; one that trips the breaker halts it. A call waiting on
the canary says so on its pulse, and a page is held from the call, before any job. A reader
holding a call file never blocks its rewrite. A refused Resume clears on the next one. The card
loses a resume flag nothing could see, and the gate a wait it set and the next poll replaced.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The runner's halt reason now follows the server state's, which keeps the first, so every caller
of two stop-class failures landing together hears the same reason, and the breaker has one
in-memory state. A caller that stops waiting no longer hears its job's later waits. Tests pin
first-come-first-served at the gate, the recheck's 35 s even when /healthz heals sooner, and
the effect behind a refused in-flight save; the direct refusals never wait on an unturned clock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The poll loop no longer turns straight round after the trouble clock trips the breaker: it waits
its interval, and the next poll cancels the job, as a trip from elsewhere does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since v0.5.0 the server's build id is git describe: a release's tag, the tag and the commits past
it, or 12 hex with no tag reachable, with -dirty for local changes. The 12-hex rule left every
output of the owner's v0.5.0 identity-unknown and the per-job mismatch trigger dead. A build is
now known when /healthz reads build.dirty false, and a job's run.build and every output's build
must equal build.id; a dirty, overridden or unknown build stays unknown. ADR 0021 is amended.
The scripted server and the ready /healthz fixture take the live v0.5.0 shape, with the 9d02636
read kept as the older server's; the smoke test now asks the cache for the bubble call again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An output fetch that gets no answer is now server trouble like a silent poll: it starts the
clock and is read again at the poll interval until the server answers or the breaker trips,
instead of three hand-counted GETs on top of the client's own re-read. A withheld output still
re-plans that candidate alone at its replay seed. The back-off checks the clock once, after its
wait. Each loop that only the clock can end is pinned by a test that drives it past 20 minutes:
a health check before a submit, a submit, a "saving inputs failed" rejection, a job the server
forgot, the canary's health check and an output fetch. The hang replay measures its cancel at
the DELETE, not at the caller's wake-up, so a busy machine cannot move it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The runner counts every ask for a canary; one that finishes clears the due flag only when nothing
asked since it started, so a mismatch, a Resume or a run's first job raised meanwhile runs the
canary again before the waiting job. A failed job that ran on another identity now asks for the
canary like a returned one; the canary's own jobs never ask, since they run on the identity they
confirm. The canary wait is cleared while a call backs off from a canary that got no answer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cache key holds no page, so a hit may be another page's call. The runner read the raw from
the requesting page's directory, missed, and silently paid for the job again; it now resolves
the output's own call and reads beside it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The gateway sends each label without its trailing sentence punctuation, but the cache key hashed
the label as given, so two requests identical on the wire had different keys. The trimming moves
to EditRect.SentLabel in UseCases, and both the payload and the key use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The server's max_retries is how often a client should resend the unchanged request. A known code
keeps its own row; an unknown retryable code that names a limit is now resent at once up to that
limit and then fails the call, charged to the stage, as server_stopped's single resend does. With
no limit it is still waited out on the clock. The resend row carries its count, and the call's
failure says it has no resend left.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each arm the review found unpinned now fails a test when broken: the running time persisted at
every stint's end (a restart resumes the 5-minute budget, not only the 20-minute one), the
back-off starting over after a partial return, an uploading job shown as queued, a job its caller
already claimed not kept for a later call, a trip answering slot waiters at once, a caller joining
a job in flight seeing its wait at once, each waiter's own place in line, and a rejected canary
submit charged to the stage and tripping the breaker. The poke on a half-up heal goes: the job's
slot, released right after, pokes every waiter anyway.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The GPU sum per page now meets a call on a page nobody asked about; a canary row the database
refuses throws rather than reading as a vanished page; models that name no weights confirm
nothing; and the Cleaning server card drops "runs before the next job" once the canary passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gen_digest_oracle.py freezes each canary canvas's digest from Pillow into digest.json beside the
raster oracle, and the test reads it rather than inline hashes; a rerun on the same versions
reproduces it byte for byte. A 16-bit grey PNG is not read as the L the server stores.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SettingsDto.EffectiveCleaningInFlight had no reader outside the tests; the runner and the card
take CleaningInFlightSetting.Default directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two callers deduped onto one job each heard its run_timeout or its hang, and
each counted it, so one failure of one job tripped the breaker. The tallies
now hold the failed jobs' rows, so a shared job counts once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The row kept the running sum only at a stint's ends, so a boot resumed
the job with its open stint lost and the 5-minute deadline fired up to a
stint late. The row now keeps when the open stint began, and a boot
resumes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A call kept showing its place in line for a slot after it had the slot,
through a slow submit and the back-off after a silent one, and a lost job's
place in the server's queue through the back-off that followed. A job's
wait clears once it has its slot, and a call's once it stops awaiting the
job.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since v0.5.0 the server reads backend_identity fresh and sends null while
ComfyUI does not answer /system_stats in time, which a running prompt can
cause. Such a read changed the fingerprint and ran the full canary. It now
compares as the backend the canary confirmed; a canary that read none
confirms none, and the first read naming one runs it again.

ADR 0021's amendment records it, with v0.5.0's fresh identity, 5 s
readiness and 10 s cancel amended in place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The build id can end -dirty or be the override or "unknown", and only the
commit and dirty go null; a null backend identity is a backend that did not
answer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A job nobody awaits is a boot's, so the flag that said so goes.
- Resume always renews the halt signal: a boot has no waiters, and Resume
  cleaning only runs on a tripped breaker.
- The raws are written without a check of their own: a page that is gone
  writes nothing, and the store refuses its outputs.
- The canary checks the server its caller saw, so it has no missing-server
  arm.
- The cache no longer guards against two outputs under one key.
- The GPU sums read a call with no GPU time as none, so a page whose calls
  read none is present with zeros, as the port says.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A call halted while it waits for a slot leaves the gate as it found it,
  and a cancel a boot waited out frees its slot.
- A job that ends done or error as its DELETE lands is final.
- A trip ends a back-off at once.
- A job put back in the queue for good is judged at its total deadline.
- A half-up verdict is waited out until the job runs again, even once
  the backend heals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The canary: a refused canary call fails the call; a caller that
  arrives mid-canary waits for that canary; looks at a silent server
  back off 2, 4, 8 s; the canary runs in full though an agent's call
  cached one of its requests.
- A job's outputs: only those asked for are taken, and only the prefix
  before the first that cannot be fetched. Each keeps the server's
  replay seed, or the asked seed where the record names none. A lone
  rerun's kept candidate lands at its own index, and a cached output
  whose raw is gone runs again.
- Also pinned: n = 0 is refused, the status's CanaryDue, and a job
  record with no models is identity-unknown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The grey arm refused a truncated PNG, but the RGB arm went through the
canonical decode, which decodes what arrived, so the two disagreed and
neither was pinned. Pillow will not open a truncated image either, and a
raw cut short is no candidate (the runner runs it again at its seed). The
canonical decode takes a whole flag for this; pages still decode as far as
their data goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs(adr): the v0.5.0 amendment in short bullets, and its in-place edits rewrapped
All checks were successful
CI / build (pull_request) Successful in 34s
CI / test (pull_request) Successful in 1m14s
ec00df5127
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

🔄 Auto-updating coverage report — this comment is regenerated on every push, so the numbers below always reflect the commit shown here, not the branch tip.

Commit: 5293192 · Generated: 2026-10-05 18:48:23 UTC · Revision: #2

Summary

Summary
Generated on: 10/05/2026 - 18:48:22
Coverage date: 10/05/2026 - 18:47:50 - 10/05/2026 - 18:48:19
Parser: MultiReport (4x Cobertura)
Assemblies: 6
Classes: 657
Files: 308
Line coverage: 97.4% (27177 of 27894)
Covered lines: 27177
Uncovered lines: 717
Coverable lines: 27894
Total lines: 48455
Branch coverage: 87.7% (5423 of 6181)
Covered branches: 5423
Total branches: 6181
Method coverage: Feature is only available for sponsors

Coverage

Orihon.BlazorAdapter - 95.8%
Name Line Branch
Orihon.BlazorAdapter 95.8% 89.2%
Orihon.BlazorAdapter.Bible.AddBeatRowRequested 100%
Orihon.BlazorAdapter.Bible.AddCharacterRowRequested 100%
Orihon.BlazorAdapter.Bible.AddGlossaryRowRequested 100%
Orihon.BlazorAdapter.Bible.AddHouseRuleRowRequested 100%
Orihon.BlazorAdapter.Bible.AddLoreRowRequested 100%
Orihon.BlazorAdapter.Bible.BibleEffects 89.8% 76.9%
Orihon.BlazorAdapter.Bible.BibleLoaded 100%
Orihon.BlazorAdapter.Bible.BiblePage 92.3% 80.5%
Orihon.BlazorAdapter.Bible.BibleReducers 90.6%
Orihon.BlazorAdapter.Bible.BibleState 100%
Orihon.BlazorAdapter.Bible.BibleWriteFailed 100%
Orihon.BlazorAdapter.Bible.DeleteBeatRowRequested 100%
Orihon.BlazorAdapter.Bible.DeleteCharacterRowRequested 100%
Orihon.BlazorAdapter.Bible.DeleteGlossaryRowRequested 100%
Orihon.BlazorAdapter.Bible.DeleteHouseRuleRowRequested 0%
Orihon.BlazorAdapter.Bible.DeleteLoreRowRequested 0%
Orihon.BlazorAdapter.Bible.LoadBible 100%
Orihon.BlazorAdapter.Bible.ReorderBeatsRequested 0%
Orihon.BlazorAdapter.Bible.SaveOverviewRequested 100%
Orihon.BlazorAdapter.Bible.SaveSummaryRequested 100%
Orihon.BlazorAdapter.Bible.UpdateBeatRowRequested 100%
Orihon.BlazorAdapter.Bible.UpdateCharacterRowRequested 100%
Orihon.BlazorAdapter.Bible.UpdateGlossaryRowRequested 100%
Orihon.BlazorAdapter.Bible.UpdateHouseRuleRowRequested 100%
Orihon.BlazorAdapter.Bible.UpdateLoreRowRequested 100%
Orihon.BlazorAdapter.BlazorAdapterAssembly 100%
Orihon.BlazorAdapter.PageWorkspace.CreateRegionRequested 100%
Orihon.BlazorAdapter.PageWorkspace.DeletePageSummaryRequested 100%
Orihon.BlazorAdapter.PageWorkspace.DeleteRegionRequested 100%
Orihon.BlazorAdapter.PageWorkspace.LoadPageWorkspace 100%
Orihon.BlazorAdapter.PageWorkspace.PageStepsLoaded 100%
Orihon.BlazorAdapter.PageWorkspace.PageSummarySaved 100%
Orihon.BlazorAdapter.PageWorkspace.PageViewport 100% 100%
Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceEffects 100% 100%
Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceLoaded 100%
Orihon.BlazorAdapter.PageWorkspace.PageWorkspacePage 93.6% 87.6%
Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceReducers 100% 64.2%
Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceState 100%
Orihon.BlazorAdapter.PageWorkspace.PageWriteFailed 100%
Orihon.BlazorAdapter.PageWorkspace.RegionColorsSampled 100%
Orihon.BlazorAdapter.PageWorkspace.RegionCreated 100%
Orihon.BlazorAdapter.PageWorkspace.RegionSaved 100%
Orihon.BlazorAdapter.PageWorkspace.ReorderRegionsRequested 100%
Orihon.BlazorAdapter.PageWorkspace.ReprocessPageRequested 100%
Orihon.BlazorAdapter.PageWorkspace.ReprocessTranslationRequested 100%
Orihon.BlazorAdapter.PageWorkspace.SampleRegionColorsRequested 100%
Orihon.BlazorAdapter.PageWorkspace.SavePageSummaryRequested 100%
Orihon.BlazorAdapter.PageWorkspace.SaveRegionRequested 100%
Orihon.BlazorAdapter.PageWorkspace.SetPageMetaRequested 100%
Orihon.BlazorAdapter.Projects.CreateProjectRequested 100%
Orihon.BlazorAdapter.Projects.DecideSetupContinuation 100%
Orihon.BlazorAdapter.Projects.DeleteProjectRequested 100%
Orihon.BlazorAdapter.Projects.FinishSetupRequested 100%
Orihon.BlazorAdapter.Projects.ImportPagesRequested 100%
Orihon.BlazorAdapter.Projects.LoadWizard 100%
Orihon.BlazorAdapter.Projects.PageOrganizer 96% 95%
Orihon.BlazorAdapter.Projects.PagesImported 100%
Orihon.BlazorAdapter.Projects.ProjectDeleteFailed 100%
Orihon.BlazorAdapter.Projects.ProjectListEffects 100% 100%
Orihon.BlazorAdapter.Projects.ProjectListPage 89.7% 91.6%
Orihon.BlazorAdapter.Projects.ProjectListReducers 100%
Orihon.BlazorAdapter.Projects.ProjectListState 100%
Orihon.BlazorAdapter.Projects.ProjectsLoaded 100%
Orihon.BlazorAdapter.Projects.ProjectWizardEffects 93.8% 90%
Orihon.BlazorAdapter.Projects.ProjectWizardPage 95.3% 84.1%
Orihon.BlazorAdapter.Projects.ProjectWizardReducers 100%
Orihon.BlazorAdapter.Projects.ProjectWizardState 100%
Orihon.BlazorAdapter.Projects.SetupChat 93.5% 100%
Orihon.BlazorAdapter.Projects.SetupChatEffects 100% 100%
Orihon.BlazorAdapter.Projects.SetupChatFailed 100%
Orihon.BlazorAdapter.Projects.SetupChatReducers 100%
Orihon.BlazorAdapter.Projects.SetupChatState 100%
Orihon.BlazorAdapter.Projects.SetupChatUpdated 100%
Orihon.BlazorAdapter.Projects.StartSetupChat 100%
Orihon.BlazorAdapter.Projects.SubmitSetupAnswer 100%
Orihon.BlazorAdapter.Projects.WizardDeletePagesRequested 100%
Orihon.BlazorAdapter.Projects.WizardLoaded 100%
Orihon.BlazorAdapter.Projects.WizardMovePagesRequested 100%
Orihon.BlazorAdapter.Projects.WizardMovePagesToNewChapterRequested 100%
Orihon.BlazorAdapter.Projects.WizardReorderPagesRequested 100%
Orihon.BlazorAdapter.Projects.WizardWriteFailed 100%
Orihon.BlazorAdapter.Rulings.AcceptProposalRequested 100%
Orihon.BlazorAdapter.Rulings.AnsweredRuling 100%
Orihon.BlazorAdapter.Rulings.AnswerRulingRequested 100%
Orihon.BlazorAdapter.Rulings.DeclineProposalRequested 100%
Orihon.BlazorAdapter.Rulings.DismissRulingRequested 100%
Orihon.BlazorAdapter.Rulings.RulingBar 98.2% 94.6%
Orihon.BlazorAdapter.Rulings.RulingDeskBridge 94.2% 91.6%
Orihon.BlazorAdapter.Rulings.RulingsEffects 95.4% 83.3%
Orihon.BlazorAdapter.Rulings.RulingsLoaded 100%
Orihon.BlazorAdapter.Rulings.RulingsReducers 100%
Orihon.BlazorAdapter.Rulings.RulingsState 100%
Orihon.BlazorAdapter.Rulings.RulingWriteFailed 100%
Orihon.BlazorAdapter.Rulings.SaveAnswerAsHouseRuleRequested 100%
Orihon.BlazorAdapter.Runs.CancelMonitorRun 100%
Orihon.BlazorAdapter.Runs.MonitorPageRef 100%
Orihon.BlazorAdapter.Runs.MonitorRunLoaded 100%
Orihon.BlazorAdapter.Runs.RetryMonitorExecution 100%
Orihon.BlazorAdapter.Runs.RunChangedBridge 95% 92.8%
Orihon.BlazorAdapter.Runs.RunMonitor 98.1% 96.9%
Orihon.BlazorAdapter.Runs.RunMonitorEffects 100% 91.6%
Orihon.BlazorAdapter.Runs.RunMonitorReducers 100%
Orihon.BlazorAdapter.Runs.RunMonitorState 100%
Orihon.BlazorAdapter.Settings.AgentDebriefsLoaded 100%
Orihon.BlazorAdapter.Settings.AgentDebriefsLoadFailed 100%
Orihon.BlazorAdapter.Settings.AgentEffortPicked 100%
Orihon.BlazorAdapter.Settings.AgentEffortSaved 100%
Orihon.BlazorAdapter.Settings.AgentEffortSaveFailed 100%
Orihon.BlazorAdapter.Settings.AgentFeedbackLoaded 100%
Orihon.BlazorAdapter.Settings.AgentFeedbackLoadFailed 0%
Orihon.BlazorAdapter.Settings.AgentModelPicked 100%
Orihon.BlazorAdapter.Settings.AgentModelSaved 100%
Orihon.BlazorAdapter.Settings.AgentModelSaveFailed 100%
Orihon.BlazorAdapter.Settings.AgentRoutingPicked 100%
Orihon.BlazorAdapter.Settings.AgentRoutingSaved 100%
Orihon.BlazorAdapter.Settings.AgentRoutingSaveFailed 0%
Orihon.BlazorAdapter.Settings.AgentTranscriptsLoaded 100%
Orihon.BlazorAdapter.Settings.AgentTranscriptsLoadFailed 0%
Orihon.BlazorAdapter.Settings.CleaningInFlightPicked 100%
Orihon.BlazorAdapter.Settings.CleaningInFlightSaveFailed 100%
Orihon.BlazorAdapter.Settings.CleaningResumed 100%
Orihon.BlazorAdapter.Settings.CleaningRunnerLoaded 100%
Orihon.BlazorAdapter.Settings.CleaningServerChecked 100%
Orihon.BlazorAdapter.Settings.CleaningServerSaved 100%
Orihon.BlazorAdapter.Settings.CleaningServerSaveFailed 100%
Orihon.BlazorAdapter.Settings.EffortOption 100% 100%
Orihon.BlazorAdapter.Settings.FloatingPassToggled 100%
Orihon.BlazorAdapter.Settings.KeySaved 100%
Orihon.BlazorAdapter.Settings.KeySaveFailed 100%
Orihon.BlazorAdapter.Settings.ModelOptionsLoaded 100%
Orihon.BlazorAdapter.Settings.ModelOptionsUnavailable 100%
Orihon.BlazorAdapter.Settings.ResumeCleaningFailed 100%
Orihon.BlazorAdapter.Settings.RoutingOption 100% 100%
Orihon.BlazorAdapter.Settings.RunConcurrencyPicked 100%
Orihon.BlazorAdapter.Settings.RunConcurrencySaveFailed 100%
Orihon.BlazorAdapter.Settings.SaveCleaningServerRequested 100%
Orihon.BlazorAdapter.Settings.SaveKeyRequested 100%
Orihon.BlazorAdapter.Settings.SettingsEffects 92.5% 83.3%
Orihon.BlazorAdapter.Settings.SettingsLoaded 100%
Orihon.BlazorAdapter.Settings.SettingsPage 97.7% 91.6%
Orihon.BlazorAdapter.Settings.SettingsReducers 96.1% 64.2%
Orihon.BlazorAdapter.Settings.SettingsState 100%
Orihon.BlazorAdapter.Settings.TranscriptFilterPicked 100%
Orihon.BlazorAdapter.Settings.TranscriptPagePicked 100%
Orihon.BlazorAdapter.Settings.TranscriptPicked 100%
Orihon.BlazorAdapter.Settings.TranscriptTextLoaded 100%
Orihon.BlazorAdapter.Settings.TranscriptTextLoadFailed 100%
Orihon.BlazorAdapter.Uploads.UploadTransfer 96.5% 100%
Orihon.BlazorAdapter.Uploads.UploadTransferProgress 100% 100%
Orihon.BlazorAdapter.Uploads.UploadTransferResult 100%
Orihon.BlazorAdapter.Workspace.CreateChapterRequested 100%
Orihon.BlazorAdapter.Workspace.DeleteChapterRequested 100%
Orihon.BlazorAdapter.Workspace.DeletePageRequested 100%
Orihon.BlazorAdapter.Workspace.DeleteSummaryRequested 100%
Orihon.BlazorAdapter.Workspace.FloatingPassAnswered 100%
Orihon.BlazorAdapter.Workspace.LoadProjectWorkspace 100%
Orihon.BlazorAdapter.Workspace.MovePageRequested 100%
Orihon.BlazorAdapter.Workspace.ProjectMetadataCard 95.6% 92.8%
Orihon.BlazorAdapter.Workspace.ProjectMetadataSaved 100%
Orihon.BlazorAdapter.Workspace.ProjectWorkspaceEffects 100% 100%
Orihon.BlazorAdapter.Workspace.ProjectWorkspaceLoaded 100%
Orihon.BlazorAdapter.Workspace.ProjectWorkspacePage 95.7% 87.9%
Orihon.BlazorAdapter.Workspace.ProjectWorkspaceReducers 100% 62.5%
Orihon.BlazorAdapter.Workspace.ProjectWorkspaceState 100%
Orihon.BlazorAdapter.Workspace.RenameChapterRequested 100%
Orihon.BlazorAdapter.Workspace.ReorderChaptersRequested 100%
Orihon.BlazorAdapter.Workspace.ReorderPagesRequested 100%
Orihon.BlazorAdapter.Workspace.RunAnnotationRequested 100%
Orihon.BlazorAdapter.Workspace.RunBibleRequested 100%
Orihon.BlazorAdapter.Workspace.RunFloatingPassRequested 100%
Orihon.BlazorAdapter.Workspace.RunTranslationRequested 100%
Orihon.BlazorAdapter.Workspace.SaveProjectMetadataRequested 100%
Orihon.BlazorAdapter.Workspace.SaveSummaryRequested 100%
Orihon.BlazorAdapter.Workspace.SetPageKindRequested 100%
Orihon.BlazorAdapter.Workspace.SummaryDeleted 100%
Orihon.BlazorAdapter.Workspace.SummarySaved 100%
Orihon.BlazorAdapter.Workspace.WorkspaceImportRequested 100%
Orihon.BlazorAdapter.Workspace.WorkspaceWriteFailed 100%
Orihon.Domain - 100%
Name Line Branch
Orihon.Domain 100% 100%
Orihon.Domain.Agents.AgentDebrief 100% 100%
Orihon.Domain.Agents.AgentDescriptor 100%
Orihon.Domain.Agents.AgentFeedback 100% 100%
Orihon.Domain.Agents.AgentRoster 100% 100%
Orihon.Domain.Bible.Character 100% 100%
Orihon.Domain.Bible.GlossaryEntry 100% 100%
Orihon.Domain.Bible.HouseRule 100%
Orihon.Domain.Bible.LoreEntry 100% 100%
Orihon.Domain.Bible.PageSummary 100%
Orihon.Domain.Bible.StoryBeat 100%
Orihon.Domain.Bible.StoryOverview 100%
Orihon.Domain.Cleaning.CleaningCall 100% 100%
Orihon.Domain.Cleaning.CleaningCallRect 100%
Orihon.Domain.Cleaning.CleaningCanvas 100%
Orihon.Domain.Cleaning.CleaningOutput 100% 100%
Orihon.Domain.Cleaning.CleaningServerIdentity 100%
Orihon.Domain.Cleaning.CleaningServerState 100% 100%
Orihon.Domain.Cleaning.CleaningWindow 100%
Orihon.Domain.Projects.Project 100% 100%
Orihon.Domain.Projects.ProjectProfile 100%
Orihon.Domain.Runs.Execution 100% 100%
Orihon.Domain.Runs.RegionProblem 100%
Orihon.Domain.Runs.Run 100%
Orihon.Domain.Settings.AppSetting 100%
Orihon.Domain.Text 100% 100%
Orihon.Domain.Translation.BoundingBox 100% 100%
Orihon.Domain.Translation.Chapter 100%
Orihon.Domain.Translation.InkColor 100% 100%
Orihon.Domain.Translation.Page 100%
Orihon.Domain.Translation.Region 100% 100%
Orihon.Domain.Translation.RegionInk 100% 100%
Orihon.Domain.Translation.RegionProfile 100%
Orihon.Infrastructure - 97.5%
Name Line Branch
Orihon.Infrastructure 97.5% 83.3%
Orihon.Infrastructure.Agents.EfAgentDebriefStore 100%
Orihon.Infrastructure.Agents.EfAgentFeedbackStore 100%
Orihon.Infrastructure.Bible.EfBibleStore 95.2% 92.8%
Orihon.Infrastructure.Cleaning.EfCleaningCallStore 98.6% 100%
Orihon.Infrastructure.DependencyInjection 100% 100%
Orihon.Infrastructure.Gateways.AgentToolAdapter 100%
Orihon.Infrastructure.Gateways.AgentToolAdapter`1 100% 100%
Orihon.Infrastructure.Gateways.AgentTranscript 95.6% 89%
Orihon.Infrastructure.Gateways.Cleaning.BoxChecks 100% 100%
Orihon.Infrastructure.Gateways.Cleaning.DerivedInk 100%
Orihon.Infrastructure.Gateways.Cleaning.FillResult 100%
Orihon.Infrastructure.Gateways.Cleaning.GateStats 100%
Orihon.Infrastructure.Gateways.Cleaning.GreyRule 100% 100%
Orihon.Infrastructure.Gateways.Cleaning.LabFill 100% 100%
Orihon.Infrastructure.Gateways.Cleaning.LabInk 100% 98.3%
Orihon.Infrastructure.Gateways.Cleaning.LabPaper 100% 97.3%
Orihon.Infrastructure.Gateways.Cleaning.PaperComponent 100%
Orihon.Infrastructure.Gateways.Cleaning.RasterCleaningImages 100% 100%
Orihon.Infrastructure.Gateways.Cleaning.RasterInkAnalyzer 100% 100%
Orihon.Infrastructure.Gateways.Cleaning.Rgb 100%
Orihon.Infrastructure.Gateways.FileSystemAgentTranscriptStore 85.2% 80.8%
Orihon.Infrastructure.Gateways.HttpWebPageFetcher 95.1% 83.3%
Orihon.Infrastructure.Gateways.LabelFont 100% 50%
Orihon.Infrastructure.Gateways.OpenRouterLlmGateway 90.2% 82.1%
Orihon.Infrastructure.Gateways.QwenImageServerGateway 96.7% 90%
Orihon.Infrastructure.Gateways.QwenImageServerJson 96% 72.3%
Orihon.Infrastructure.Gateways.Raster.FloatImage 66.6% 50%
Orihon.Infrastructure.Gateways.Raster.GrayImage 87.5% 75%
Orihon.Infrastructure.Gateways.Raster.Labels 100% 100%
Orihon.Infrastructure.Gateways.Raster.Mask 95.6% 92.6%
Orihon.Infrastructure.Gateways.Raster.NumpyMath 93.9% 93.4%
Orihon.Infrastructure.Gateways.Raster.PillowBlur 98.4% 89.4%
Orihon.Infrastructure.Gateways.Raster.PillowLanczos 100% 100%
Orihon.Infrastructure.Gateways.Raster.PixelBox 100% 100%
Orihon.Infrastructure.Gateways.Raster.RgbImage 96.4% 75%
Orihon.Infrastructure.Gateways.Raster.ScipyGaussian 100% 100%
Orihon.Infrastructure.Gateways.SkiaImages 100% 100%
Orihon.Infrastructure.Gateways.SkiaPageImageRenderer 97.4% 90.8%
Orihon.Infrastructure.Gateways.SkiaPixelDigest 100% 100%
Orihon.Infrastructure.Gateways.SkiaRegionColorSampler 100% 100%
Orihon.Infrastructure.Gateways.UntaggedPng 100% 100%
Orihon.Infrastructure.Persistence.Configurations.AgentDebriefConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.AgentFeedbackConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.AppSettingConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.ChapterConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.CharacterConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.CleaningCallConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.CleaningOutputConfiguratio
n
100%
Orihon.Infrastructure.Persistence.Configurations.CleaningServerStateConfigu
ration
100%
Orihon.Infrastructure.Persistence.Configurations.ExecutionConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.GlossaryEntryConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.HouseRuleConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.JsonColumnMapper 100%
Orihon.Infrastructure.Persistence.Configurations.LoreEntryConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.PageConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.PageSummaryConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.ProjectConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.RegionConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.RunConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.StoryBeatConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.StoryOverviewConfiguration 100%
Orihon.Infrastructure.Persistence.Converters.UtcTicksConverter 100%
Orihon.Infrastructure.Persistence.Migrations.AddAgentDebriefs 99.5%
Orihon.Infrastructure.Persistence.Migrations.AddAgentFeedback 99.5%
Orihon.Infrastructure.Persistence.Migrations.AddAppSettings 99.3%
Orihon.Infrastructure.Persistence.Migrations.AddCleaningCallRunner 99.3%
Orihon.Infrastructure.Persistence.Migrations.AddExecutionFeedbackRegions 99.3%
Orihon.Infrastructure.Persistence.Migrations.AddHouseRules 99.6%
Orihon.Infrastructure.Persistence.Migrations.AddPagePassFacts 99%
Orihon.Infrastructure.Persistence.Migrations.AddProjectSourceLanguage 99.3%
Orihon.Infrastructure.Persistence.Migrations.AddRegionFitBoxDropFillHints 98.1%
Orihon.Infrastructure.Persistence.Migrations.AddRegionForm 99.4%
Orihon.Infrastructure.Persistence.Migrations.AddRegionInk 99.4%
Orihon.Infrastructure.Persistence.Migrations.AddRuns 99.1%
Orihon.Infrastructure.Persistence.Migrations.AddStoryOverview 99.5%
Orihon.Infrastructure.Persistence.Migrations.DropRegionContainer 99.1%
Orihon.Infrastructure.Persistence.Migrations.DropRegionType 99%
Orihon.Infrastructure.Persistence.Migrations.InitialTranslationDomain 97.3%
Orihon.Infrastructure.Persistence.Migrations.OrihonDbContextModelSnapshot 100%
Orihon.Infrastructure.Persistence.Migrations.RenameSourceTargetColumns 97.2%
Orihon.Infrastructure.Persistence.Migrations.ReplaceFitBoxWithContainerSeed 99.2%
Orihon.Infrastructure.Persistence.OrihonDbContext 100%
Orihon.Infrastructure.Persistence.OrihonDbContextFactory 100%
Orihon.Infrastructure.Projects.EfProjectStore 100% 100%
Orihon.Infrastructure.Projects.FileSystemPageImageStore 100% 100%
Orihon.Infrastructure.Runs.EfRunStore 98.2% 75%
Orihon.Infrastructure.Settings.EfAppSettingsStore 100% 100%
Orihon.Infrastructure.Translation.EfChapterStore 100% 100%
Orihon.Infrastructure.Translation.EfPageStore 98.3% 93.7%
Orihon.Infrastructure.Translation.EfRegionStore 100% 100%
Orihon.Infrastructure.Translation.Ordering 100% 100%
System.Text.RegularExpressions.Generated 70.6% 53.3%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlankLines_4
77.9% 76.6%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlockBreaks_1
59% 42.5%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__SpaceRuns_3
89.4% 75%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__Tags_2
83.7% 62.5%
Orihon.Kernel - 90.9%
Name Line Branch
Orihon.Kernel 90.9% 75%
Orihon.Kernel.Err`1 100%
Orihon.Kernel.Ok`1 100%
Orihon.Kernel.Result`1 88.8% 75%
Orihon.Server - 94.6%
Name Line Branch
Orihon.Server 94.6% 79.4%
Orihon.Server.CleaningCallRunnerBootstrap 100%
Orihon.Server.Components.App 100%
Orihon.Server.Components.Layout.MainLayout 100%
Orihon.Server.Components.Pages.Gate 64.2% 66.6%
Orihon.Server.Diagnostics.FakeCleaningServer 94.6% 80.7%
Orihon.Server.RunEngineBootstrap 100%
Orihon.Server.Security.AccessGate 91.8% 41.6%
Orihon.Server.Security.AccessSecret 100% 50%
Orihon.Server.VolumeStartupValidator 100% 100%
Program 95.7% 85.7%
Orihon.UseCases - 97.6%
Name Line Branch
Orihon.UseCases 97.6% 90.9%
Orihon.UseCases.Agents.AgentAttemptPreparation 100%
Orihon.UseCases.Agents.AgentAttemptSupport 98.6% 98.3%
Orihon.UseCases.Agents.AgentBlueprint 100%
Orihon.UseCases.Agents.AgentCapDebrief 100%
Orihon.UseCases.Agents.AgentInvocation 100%
Orihon.UseCases.Agents.AgentOutcome 100%
Orihon.UseCases.Agents.AgentTool`1 90.9% 75%
Orihon.UseCases.Agents.AgentToolImage 100%
Orihon.UseCases.Agents.AgentToolResult 100%
Orihon.UseCases.Agents.Annotation.AddFloatingRegionParams 100%
Orihon.UseCases.Agents.Annotation.AddFloatingRegionTool 95.8% 75%
Orihon.UseCases.Agents.Annotation.AddRegionParams 100%
Orihon.UseCases.Agents.Annotation.AddRegionTool 95.4% 75%
Orihon.UseCases.Agents.Annotation.AnnotationBlueprints 100%
Orihon.UseCases.Agents.Annotation.AnnotationStage 100% 86.1%
Orihon.UseCases.Agents.Annotation.BboxCreationExecutor 90.4% 50%
Orihon.UseCases.Agents.Annotation.BboxRefinementExecutor 96.5% 90%
Orihon.UseCases.Agents.Annotation.BoundBoxParams 100%
Orihon.UseCases.Agents.Annotation.BoundContactSheetTool 91.3% 75%
Orihon.UseCases.Agents.Annotation.BoundCropParams 100%
Orihon.UseCases.Agents.Annotation.BoundCropTool 100%
Orihon.UseCases.Agents.Annotation.BoundViewPageTool 93.1% 80%
Orihon.UseCases.Agents.Annotation.BoundViewParams 100%
Orihon.UseCases.Agents.Annotation.ClassifyRegionParams 100%
Orihon.UseCases.Agents.Annotation.ClassifyRegionTool 100% 100%
Orihon.UseCases.Agents.Annotation.ColorReading 100% 100%
Orihon.UseCases.Agents.Annotation.DeleteBoundRegionTool 100% 100%
Orihon.UseCases.Agents.Annotation.DeleteRegionParams 100%
Orihon.UseCases.Agents.Annotation.DeleteRegionTool 100% 100%
Orihon.UseCases.Agents.Annotation.FindGlossaryParams 100%
Orihon.UseCases.Agents.Annotation.FindGlossaryTool 88.2% 62.5%
Orihon.UseCases.Agents.Annotation.FloatingCreationExecutor 86.9% 50%
Orihon.UseCases.Agents.Annotation.FloatingQaExecutor 91.8% 78.5%
Orihon.UseCases.Agents.Annotation.FloatingTranscriptionExecutor 95.4% 75%
Orihon.UseCases.Agents.Annotation.ListRegionsTool 93.7% 80.7%
Orihon.UseCases.Agents.Annotation.MoveResizeBoundTool 90.9% 50%
Orihon.UseCases.Agents.Annotation.MoveResizeRegionParams 100%
Orihon.UseCases.Agents.Annotation.MoveResizeRegionTool 95.8% 83.3%
Orihon.UseCases.Agents.Annotation.NoteRegionParams 100%
Orihon.UseCases.Agents.Annotation.NoteRegionTool 100% 100%
Orihon.UseCases.Agents.Annotation.PageQaExecutor 92.5% 79.1%
Orihon.UseCases.Agents.Annotation.QaReportSink 100% 100%
Orihon.UseCases.Agents.Annotation.RegionAuthoringAccess 89.4% 62.5%
Orihon.UseCases.Agents.Annotation.RegionBriefing 100% 96.1%
Orihon.UseCases.Agents.Annotation.RegionCropParams 100%
Orihon.UseCases.Agents.Annotation.RegionCropTool 100% 100%
Orihon.UseCases.Agents.Annotation.RegionProblemParams 100%
Orihon.UseCases.Agents.Annotation.RegionWindow 100% 100%
Orihon.UseCases.Agents.Annotation.RejectRegionParams 100%
Orihon.UseCases.Agents.Annotation.RejectRegionTool 100% 100%
Orihon.UseCases.Agents.Annotation.ReorderRegionParams 100%
Orihon.UseCases.Agents.Annotation.ReorderRegionTool 88% 60%
Orihon.UseCases.Agents.Annotation.ReportQaParams 100%
Orihon.UseCases.Agents.Annotation.ReportQaTool 97.8% 90%
Orihon.UseCases.Agents.Annotation.SampleColorsParams 100%
Orihon.UseCases.Agents.Annotation.SampleColorsTool 100% 100%
Orihon.UseCases.Agents.Annotation.SampleRegionColorsParams 100%
Orihon.UseCases.Agents.Annotation.SampleRegionColorsTool 100% 100%
Orihon.UseCases.Agents.Annotation.SetInkParams 100%
Orihon.UseCases.Agents.Annotation.SetInkTool 100% 100%
Orihon.UseCases.Agents.Annotation.SetPageMetaParams 100%
Orihon.UseCases.Agents.Annotation.SetPageMetaTool 100% 75%
Orihon.UseCases.Agents.Annotation.SetRegionInkParams 100%
Orihon.UseCases.Agents.Annotation.SetRegionInkTool 100% 100%
Orihon.UseCases.Agents.Annotation.SetTranscriptionParams 100%
Orihon.UseCases.Agents.Annotation.SetTranscriptionTool 100% 100%
Orihon.UseCases.Agents.Annotation.TranscriptionExecutor 97.7% 94.4%
Orihon.UseCases.Agents.AssistantSpoke 100%
Orihon.UseCases.Agents.BibleBuilding.BibleBuildingBlueprint 100%
Orihon.UseCases.Agents.BibleBuilding.BibleBuildingExecutor 96.9% 75%
Orihon.UseCases.Agents.BibleBuilding.GetRegionParams 100%
Orihon.UseCases.Agents.BibleBuilding.GetRegionTool 84.6% 70%
Orihon.UseCases.Agents.BibleBuilding.ListProjectRegionsTool 86.3% 83.3%
Orihon.UseCases.Agents.BibleBuilding.ListRegionsParams 100%
Orihon.UseCases.Agents.Inspection.PageImageAccess 95.2% 80.6%
Orihon.UseCases.Agents.Inspection.ViewAccount 100% 100%
Orihon.UseCases.Agents.ReportFrictionParams 100%
Orihon.UseCases.Agents.ReportFrictionTool 100% 92.8%
Orihon.UseCases.Agents.ResearchSetup.AddStoryBeatParams 100%
Orihon.UseCases.Agents.ResearchSetup.AddStoryBeatTool 100% 75%
Orihon.UseCases.Agents.ResearchSetup.AskUserParams 100%
Orihon.UseCases.Agents.ResearchSetup.AskUserTool 100% 100%
Orihon.UseCases.Agents.ResearchSetup.DeleteStoryBeatParams 100%
Orihon.UseCases.Agents.ResearchSetup.DeleteStoryBeatTool 100% 100%
Orihon.UseCases.Agents.ResearchSetup.FetchUrlParams 100%
Orihon.UseCases.Agents.ResearchSetup.FetchUrlTool 100% 100%
Orihon.UseCases.Agents.ResearchSetup.ListBibleTool 90.3% 66.6%
Orihon.UseCases.Agents.ResearchSetup.ListPagesTool 97% 83.3%
Orihon.UseCases.Agents.ResearchSetup.LocatedPage 100%
Orihon.UseCases.Agents.ResearchSetup.PageByNumber 95% 91.6%
Orihon.UseCases.Agents.ResearchSetup.ResearchSetupBlueprint 100%
Orihon.UseCases.Agents.ResearchSetup.SetPageMetaParams 100%
Orihon.UseCases.Agents.ResearchSetup.SetPageMetaTool 95.2% 90%
Orihon.UseCases.Agents.ResearchSetup.SetPageSummaryParams 100%
Orihon.UseCases.Agents.ResearchSetup.SetPageSummaryTool 95.8% 75%
Orihon.UseCases.Agents.ResearchSetup.SetProjectMetadataParams 100%
Orihon.UseCases.Agents.ResearchSetup.SetProjectMetadataTool 96.5% 95.8%
Orihon.UseCases.Agents.ResearchSetup.SetStoryOverviewParams 100%
Orihon.UseCases.Agents.ResearchSetup.SetStoryOverviewTool 100% 100%
Orihon.UseCases.Agents.ResearchSetup.StoryBeatByNumber 100% 100%
Orihon.UseCases.Agents.ResearchSetup.UpdateStoryBeatParams 100%
Orihon.UseCases.Agents.ResearchSetup.UpdateStoryBeatTool 100% 75%
Orihon.UseCases.Agents.ResearchSetup.UpsertCharacterParams 100%
Orihon.UseCases.Agents.ResearchSetup.UpsertCharacterTool 92.3% 71.4%
Orihon.UseCases.Agents.ResearchSetup.UpsertGlossaryParams 100%
Orihon.UseCases.Agents.ResearchSetup.UpsertGlossaryTool 97.4% 90%
Orihon.UseCases.Agents.ResearchSetup.UpsertLoreParams 100%
Orihon.UseCases.Agents.ResearchSetup.UpsertLoreTool 92.3% 71.4%
Orihon.UseCases.Agents.ResearchSetup.ViewPageParams 100%
Orihon.UseCases.Agents.ResearchSetup.ViewPageTool 100% 100%
Orihon.UseCases.Agents.RoundStarted 100%
Orihon.UseCases.Agents.Rulings.AnswerRuling 100%
Orihon.UseCases.Agents.Rulings.DismissRuling 100%
Orihon.UseCases.Agents.Rulings.HouseRuleProposal 100%
Orihon.UseCases.Agents.Rulings.ListPendingRulings 100%
Orihon.UseCases.Agents.Rulings.ListRuleProposals 100%
Orihon.UseCases.Agents.Rulings.PendingRuling 100%
Orihon.UseCases.Agents.Rulings.ProposeHouseRuleParams 100%
Orihon.UseCases.Agents.Rulings.ProposeHouseRuleTool 100% 100%
Orihon.UseCases.Agents.Rulings.RequestRulingParams 100%
Orihon.UseCases.Agents.Rulings.RequestRulingTool 100% 81.2%
Orihon.UseCases.Agents.Rulings.RulingAnswer 100%
Orihon.UseCases.Agents.Rulings.RulingDesk 97.8% 80%
Orihon.UseCases.Agents.Rulings.RulingOption 100%
Orihon.UseCases.Agents.Rulings.RulingOptionParams 100%
Orihon.UseCases.Agents.Rulings.SettledRuling 100%
Orihon.UseCases.Agents.Rulings.WithdrawRuleProposal 100%
Orihon.UseCases.Agents.Setup.ResearchSetupExecutor 98.5% 92.8%
Orihon.UseCases.Agents.Setup.SetupChatEntry 100%
Orihon.UseCases.Agents.Setup.SetupConversation 100% 87.5%
Orihon.UseCases.Agents.Setup.SetupConversationRegistry 100%
Orihon.UseCases.Agents.ToolCalled 100%
Orihon.UseCases.Agents.ToolCompleted 100%
Orihon.UseCases.Agents.TranscriptLabel 100% 100%
Orihon.UseCases.Agents.Translation.GetPageSummaryParams 100%
Orihon.UseCases.Agents.Translation.GetPageSummaryTool 80% 66.6%
Orihon.UseCases.Agents.Translation.SetTranslationParams 100%
Orihon.UseCases.Agents.Translation.SetTranslationTool 88.5% 78.5%
Orihon.UseCases.Agents.Translation.TranslationBlueprint 100%
Orihon.UseCases.Agents.Translation.TranslationExecutor 93.8% 71.4%
Orihon.UseCases.Agents.Translation.UpdateGlossaryEnParams 100%
Orihon.UseCases.Agents.Translation.UpdateGlossaryEnTool 82.6% 62.5%
Orihon.UseCases.Bible.AddCharacter 100% 100%
Orihon.UseCases.Bible.AddGlossaryEntry 100% 100%
Orihon.UseCases.Bible.AddHouseRule 100% 100%
Orihon.UseCases.Bible.AddLoreEntry 100% 100%
Orihon.UseCases.Bible.AddStoryBeat 100% 100%
Orihon.UseCases.Bible.BibleDto 100%
Orihon.UseCases.Bible.CharacterDto 100%
Orihon.UseCases.Bible.DeleteCharacter 100% 100%
Orihon.UseCases.Bible.DeleteGlossaryEntry 100% 100%
Orihon.UseCases.Bible.DeleteHouseRule 100% 100%
Orihon.UseCases.Bible.DeleteLoreEntry 100% 100%
Orihon.UseCases.Bible.DeletePageSummary 100% 100%
Orihon.UseCases.Bible.DeleteStoryBeat 100% 100%
Orihon.UseCases.Bible.GetBible 100% 100%
Orihon.UseCases.Bible.GlossaryEntryDto 100%
Orihon.UseCases.Bible.HouseRuleDto 100%
Orihon.UseCases.Bible.LoreEntryDto 100%
Orihon.UseCases.Bible.PageSummaryDto 100%
Orihon.UseCases.Bible.ReorderStoryBeats 100%
Orihon.UseCases.Bible.SetPageSummary 100% 100%
Orihon.UseCases.Bible.SetStoryOverview 100% 100%
Orihon.UseCases.Bible.StoryBeatDto 100%
Orihon.UseCases.Bible.StoryOverviewDto 100%
Orihon.UseCases.Bible.UpdateCharacter 100% 100%
Orihon.UseCases.Bible.UpdateGlossaryEntry 100% 100%
Orihon.UseCases.Bible.UpdateHouseRule 100% 100%
Orihon.UseCases.Bible.UpdateLoreEntry 100% 100%
Orihon.UseCases.Bible.UpdateStoryBeat 100% 100%
Orihon.UseCases.Chapters.ChapterDto 100%
Orihon.UseCases.Chapters.CreateChapter 100% 100%
Orihon.UseCases.Chapters.DeleteChapter 100% 100%
Orihon.UseCases.Chapters.RenameChapter 100% 100%
Orihon.UseCases.Chapters.ReorderChapters 100%
Orihon.UseCases.Cleaning.CanaryShape 100% 50%
Orihon.UseCases.Cleaning.CleaningCacheKey 100% 100%
Orihon.UseCases.Cleaning.CleaningCallFailed 100%
Orihon.UseCases.Cleaning.CleaningCallHalted 100%
Orihon.UseCases.Cleaning.CleaningCallRequest 100%
Orihon.UseCases.Cleaning.CleaningCallReturned 100%
Orihon.UseCases.Cleaning.CleaningCallRunner 97.1% 95.1%
Orihon.UseCases.Cleaning.CleaningCanary 100%
Orihon.UseCases.Cleaning.CleaningCandidate 80%
Orihon.UseCases.Cleaning.CleaningFailure 100%
Orihon.UseCases.Cleaning.CleaningFailures 100% 97.6%
Orihon.UseCases.Cleaning.CleaningGpuTime 100%
Orihon.UseCases.Cleaning.CleaningHealth 100% 100%
Orihon.UseCases.Cleaning.CleaningIdentity 100% 89.7%
Orihon.UseCases.Cleaning.CleaningRecipe 100%
Orihon.UseCases.Cleaning.CleaningRunnerOptions 100%
Orihon.UseCases.Cleaning.CleaningRunnerStatus 100%
Orihon.UseCases.Cleaning.GetCleaningRunnerStatus 100%
Orihon.UseCases.Cleaning.GpuWait 100%
Orihon.UseCases.Cleaning.JobClock 100% 100%
Orihon.UseCases.Cleaning.JobIdentity 100%
Orihon.UseCases.Cleaning.ResumeCleaning 100% 100%
Orihon.UseCases.Cleaning.UploadNotes 100%
Orihon.UseCases.Debriefs.AgentDebriefDto 90.9%
Orihon.UseCases.Debriefs.AgentFeedbackDto 83.3%
Orihon.UseCases.Debriefs.ClearAgentDebriefs 100%
Orihon.UseCases.Debriefs.ClearAgentFeedback 100%
Orihon.UseCases.Debriefs.ListAgentDebriefs 100% 100%
Orihon.UseCases.Debriefs.ListAgentFeedback 100% 75%
Orihon.UseCases.DependencyInjection 100%
Orihon.UseCases.Diagnostics.FakeCleaningServerAddress 100%
Orihon.UseCases.Diagnostics.SeedDevData 99.2% 82.1%
Orihon.UseCases.Gateways.BoxFlag 100%
Orihon.UseCases.Gateways.ClosedBalloon 100%
Orihon.UseCases.Gateways.ColorShare 100%
Orihon.UseCases.Gateways.EditBackendError 100%
Orihon.UseCases.Gateways.EditBackendIdentity 100%
Orihon.UseCases.Gateways.EditJob 100%
Orihon.UseCases.Gateways.EditJobAccepted 100%
Orihon.UseCases.Gateways.EditJobRejected 100%
Orihon.UseCases.Gateways.EditJobRequest 86.6% 66.6%
Orihon.UseCases.Gateways.EditJobRun 100%
Orihon.UseCases.Gateways.EditModels 100%
Orihon.UseCases.Gateways.EditModelWeight 100%
Orihon.UseCases.Gateways.EditOutputImage 100%
Orihon.UseCases.Gateways.EditOutputWithheld 100%
Orihon.UseCases.Gateways.EditRect 100% 100%
Orihon.UseCases.Gateways.EditRunOutput 100%
Orihon.UseCases.Gateways.EditServerAnswered`1 100%
Orihon.UseCases.Gateways.EditServerBuild 100%
Orihon.UseCases.Gateways.EditServerHealth 100%
Orihon.UseCases.Gateways.EditServerSilent`1 100%
Orihon.UseCases.Gateways.FillRefusal 100%
Orihon.UseCases.Gateways.FillReport 100%
Orihon.UseCases.Gateways.GlyphFill 100%
Orihon.UseCases.Gateways.GridAxis 100%
Orihon.UseCases.Gateways.GridSteps 100%
Orihon.UseCases.Gateways.InkFacts 100%
Orihon.UseCases.Gateways.InkRegion 100%
Orihon.UseCases.Gateways.LabeledBox 100%
Orihon.UseCases.Gateways.LlmKeyInfo 100%
Orihon.UseCases.Gateways.LlmModel 100%
Orihon.UseCases.Gateways.LlmReasoning 100% 100%
Orihon.UseCases.Gateways.PageTone 100%
Orihon.UseCases.Gateways.PaperColor 100%
Orihon.UseCases.Gateways.PixelDigest 100%
Orihon.UseCases.Gateways.PixelMask 100%
Orihon.UseCases.Gateways.PixelRect 100%
Orihon.UseCases.Gateways.PixelWindow 100%
Orihon.UseCases.Gateways.RenderedView 100%
Orihon.UseCases.Gateways.StoredTranscript 100%
Orihon.UseCases.Gateways.StoredTranscriptPage 100%
Orihon.UseCases.Gateways.TranscriptHeader 97.3% 90.9%
Orihon.UseCases.Gateways.TranscriptListingFacets 100%
Orihon.UseCases.Gateways.TranscriptSummary 100%
Orihon.UseCases.Gateways.WindowUpload 100%
Orihon.UseCases.NextOrder 100%
Orihon.UseCases.Pages.DeletePage 100% 100%
Orihon.UseCases.Pages.DeletePages 100% 100%
Orihon.UseCases.Pages.GetPage 100% 100%
Orihon.UseCases.Pages.GetPageSteps 100% 100%
Orihon.UseCases.Pages.GetProjectWorkspace 100% 100%
Orihon.UseCases.Pages.ImportPages 100% 100%
Orihon.UseCases.Pages.ImportPagesResult 100%
Orihon.UseCases.Pages.MarkPageAnnotated 100% 100%
Orihon.UseCases.Pages.MarkPagePasses 100% 50%
Orihon.UseCases.Pages.MovePage 100% 93.7%
Orihon.UseCases.Pages.MovePages 100% 100%
Orihon.UseCases.Pages.PageDetailDto 100%
Orihon.UseCases.Pages.PageDto 100%
Orihon.UseCases.Pages.PageStepsDto 100%
Orihon.UseCases.Pages.PageUpload 100%
Orihon.UseCases.Pages.ProjectWorkspaceDto 100%
Orihon.UseCases.Pages.ReorderPages 100%
Orihon.UseCases.Pages.SetPageMeta 100% 100%
Orihon.UseCases.Pages.WorkspaceChapterDto 100%
Orihon.UseCases.Projects.CompleteProjectSetup 100% 93.7%
Orihon.UseCases.Projects.CreateProject 100% 100%
Orihon.UseCases.Projects.DeleteProject 100% 100%
Orihon.UseCases.Projects.FloatingPassAnswer 100%
Orihon.UseCases.Projects.GetProject 100% 100%
Orihon.UseCases.Projects.ListProjects 100%
Orihon.UseCases.Projects.PageMention 100%
Orihon.UseCases.Projects.ProjectDto 96.1%
Orihon.UseCases.Projects.StartAnnotationRun 96.5% 92.8%
Orihon.UseCases.Projects.StartBibleRun 92.3% 83.3%
Orihon.UseCases.Projects.StartFloatingPassRun 100% 100%
Orihon.UseCases.Projects.StartSetupRun 100% 100%
Orihon.UseCases.Projects.StartTranslationRun 92.3% 83.3%
Orihon.UseCases.Projects.StoredPageImage 100%
Orihon.UseCases.Projects.UpdateProjectMetadata 100% 100%
Orihon.UseCases.Regions.CreateRegion 100% 100%
Orihon.UseCases.Regions.DeleteRegion 100% 100%
Orihon.UseCases.Regions.RegionDto 96.8%
Orihon.UseCases.Regions.ReorderRegions 100%
Orihon.UseCases.Regions.SampleRegionColors 100% 50%
Orihon.UseCases.Regions.UpdateRegion 100% 100%
Orihon.UseCases.Runs.AnnotationPipeline 100% 100%
Orihon.UseCases.Runs.AttemptLedger 100% 100%
Orihon.UseCases.Runs.ExecutionDto 93.3%
Orihon.UseCases.Runs.ExecutionProgress 100%
Orihon.UseCases.Runs.ExecutionProgressRegistry 100% 100%
Orihon.UseCases.Runs.ExecutionPulseRelay 100% 100%
Orihon.UseCases.Runs.ExecutionSendBack 100%
Orihon.UseCases.Runs.PlannedExecution 100%
Orihon.UseCases.Runs.PulseTarget 100%
Orihon.UseCases.Runs.ReprocessPage 97% 95.8%
Orihon.UseCases.Runs.ReprocessTranslation 88.8% 83.3%
Orihon.UseCases.Runs.RunDto 93.3% 90%
Orihon.UseCases.Runs.RunEngine 95.8% 94%
Orihon.UseCases.Runs.RunEngineOptions 100% 100%
Orihon.UseCases.Runs.RunPhase 94.1% 100%
Orihon.UseCases.Runs.RunStart 100%
Orihon.UseCases.Runs.StageContext 100% 50%
Orihon.UseCases.Runs.StageHaltedException 100%
Orihon.UseCases.Runs.WorkStates 100% 83.3%
Orihon.UseCases.Settings.AgentSettingDto 100% 100%
Orihon.UseCases.Settings.CheckCleaningServer 87.5% 60%
Orihon.UseCases.Settings.CleaningInFlightSetting 100% 100%
Orihon.UseCases.Settings.CleaningServerSetting 100% 100%
Orihon.UseCases.Settings.CleaningServerStatusDto 100% 100%
Orihon.UseCases.Settings.ConcurrencySetting 100% 100%
Orihon.UseCases.Settings.EffortSetting 100% 100%
Orihon.UseCases.Settings.GetSettings 100% 100%
Orihon.UseCases.Settings.ListModelOptions 100% 100%
Orihon.UseCases.Settings.RoutingSetting 100% 100%
Orihon.UseCases.Settings.SaveAgentEffort 100% 100%
Orihon.UseCases.Settings.SaveAgentModel 100% 100%
Orihon.UseCases.Settings.SaveAgentRouting 100% 100%
Orihon.UseCases.Settings.SaveCleaningInFlight 100% 100%
Orihon.UseCases.Settings.SaveCleaningServer 95.2% 85.7%
Orihon.UseCases.Settings.SaveFloatingPass 100% 100%
Orihon.UseCases.Settings.SaveOpenRouterKey 100% 100%
Orihon.UseCases.Settings.SaveRunConcurrency 100% 100%
Orihon.UseCases.Settings.SettingKeys 100% 100%
Orihon.UseCases.Settings.SettingsDto 100% 100%
Orihon.UseCases.Transcripts.AgentTranscriptDto 100%
Orihon.UseCases.Transcripts.AgentTranscriptListDto 100%
Orihon.UseCases.Transcripts.AgentTranscriptPageDto 100%
Orihon.UseCases.Transcripts.AgentTranscriptTextDto 100%
Orihon.UseCases.Transcripts.ClearAgentTranscripts 100% 100%
Orihon.UseCases.Transcripts.ListAgentTranscripts 100% 100%
Orihon.UseCases.Transcripts.ReadAgentTranscript 100% 100%
<!-- coverage-comment --> > 🔄 **Auto-updating coverage report** — this comment is regenerated on every push, so the numbers below always reflect the commit shown here, not the branch tip. > > **Commit:** `5293192` · **Generated:** 2026-10-05 18:48:23 UTC · **Revision:** #2 # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 10/05/2026 - 18:48:22 | | Coverage date: | 10/05/2026 - 18:47:50 - 10/05/2026 - 18:48:19 | | Parser: | MultiReport (4x Cobertura) | | Assemblies: | 6 | | Classes: | 657 | | Files: | 308 | | **Line coverage:** | 97.4% (27177 of 27894) | | Covered lines: | 27177 | | Uncovered lines: | 717 | | Coverable lines: | 27894 | | Total lines: | 48455 | | **Branch coverage:** | 87.7% (5423 of 6181) | | Covered branches: | 5423 | | Total branches: | 6181 | | **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) | </details> ## Coverage <details><summary>Orihon.BlazorAdapter - 95.8%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.BlazorAdapter**|**95.8%**|**89.2%**| |Orihon.BlazorAdapter.Bible.AddBeatRowRequested|100%|| |Orihon.BlazorAdapter.Bible.AddCharacterRowRequested|100%|| |Orihon.BlazorAdapter.Bible.AddGlossaryRowRequested|100%|| |Orihon.BlazorAdapter.Bible.AddHouseRuleRowRequested|100%|| |Orihon.BlazorAdapter.Bible.AddLoreRowRequested|100%|| |Orihon.BlazorAdapter.Bible.BibleEffects|89.8%|76.9%| |Orihon.BlazorAdapter.Bible.BibleLoaded|100%|| |Orihon.BlazorAdapter.Bible.BiblePage|92.3%|80.5%| |Orihon.BlazorAdapter.Bible.BibleReducers|90.6%|| |Orihon.BlazorAdapter.Bible.BibleState|100%|| |Orihon.BlazorAdapter.Bible.BibleWriteFailed|100%|| |Orihon.BlazorAdapter.Bible.DeleteBeatRowRequested|100%|| |Orihon.BlazorAdapter.Bible.DeleteCharacterRowRequested|100%|| |Orihon.BlazorAdapter.Bible.DeleteGlossaryRowRequested|100%|| |Orihon.BlazorAdapter.Bible.DeleteHouseRuleRowRequested|0%|| |Orihon.BlazorAdapter.Bible.DeleteLoreRowRequested|0%|| |Orihon.BlazorAdapter.Bible.LoadBible|100%|| |Orihon.BlazorAdapter.Bible.ReorderBeatsRequested|0%|| |Orihon.BlazorAdapter.Bible.SaveOverviewRequested|100%|| |Orihon.BlazorAdapter.Bible.SaveSummaryRequested|100%|| |Orihon.BlazorAdapter.Bible.UpdateBeatRowRequested|100%|| |Orihon.BlazorAdapter.Bible.UpdateCharacterRowRequested|100%|| |Orihon.BlazorAdapter.Bible.UpdateGlossaryRowRequested|100%|| |Orihon.BlazorAdapter.Bible.UpdateHouseRuleRowRequested|100%|| |Orihon.BlazorAdapter.Bible.UpdateLoreRowRequested|100%|| |Orihon.BlazorAdapter.BlazorAdapterAssembly|100%|| |Orihon.BlazorAdapter.PageWorkspace.CreateRegionRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.DeletePageSummaryRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.DeleteRegionRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.LoadPageWorkspace|100%|| |Orihon.BlazorAdapter.PageWorkspace.PageStepsLoaded|100%|| |Orihon.BlazorAdapter.PageWorkspace.PageSummarySaved|100%|| |Orihon.BlazorAdapter.PageWorkspace.PageViewport|100%|100%| |Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceEffects|100%|100%| |Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceLoaded|100%|| |Orihon.BlazorAdapter.PageWorkspace.PageWorkspacePage|93.6%|87.6%| |Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceReducers|100%|64.2%| |Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceState|100%|| |Orihon.BlazorAdapter.PageWorkspace.PageWriteFailed|100%|| |Orihon.BlazorAdapter.PageWorkspace.RegionColorsSampled|100%|| |Orihon.BlazorAdapter.PageWorkspace.RegionCreated|100%|| |Orihon.BlazorAdapter.PageWorkspace.RegionSaved|100%|| |Orihon.BlazorAdapter.PageWorkspace.ReorderRegionsRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.ReprocessPageRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.ReprocessTranslationRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.SampleRegionColorsRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.SavePageSummaryRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.SaveRegionRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.SetPageMetaRequested|100%|| |Orihon.BlazorAdapter.Projects.CreateProjectRequested|100%|| |Orihon.BlazorAdapter.Projects.DecideSetupContinuation|100%|| |Orihon.BlazorAdapter.Projects.DeleteProjectRequested|100%|| |Orihon.BlazorAdapter.Projects.FinishSetupRequested|100%|| |Orihon.BlazorAdapter.Projects.ImportPagesRequested|100%|| |Orihon.BlazorAdapter.Projects.LoadWizard|100%|| |Orihon.BlazorAdapter.Projects.PageOrganizer|96%|95%| |Orihon.BlazorAdapter.Projects.PagesImported|100%|| |Orihon.BlazorAdapter.Projects.ProjectDeleteFailed|100%|| |Orihon.BlazorAdapter.Projects.ProjectListEffects|100%|100%| |Orihon.BlazorAdapter.Projects.ProjectListPage|89.7%|91.6%| |Orihon.BlazorAdapter.Projects.ProjectListReducers|100%|| |Orihon.BlazorAdapter.Projects.ProjectListState|100%|| |Orihon.BlazorAdapter.Projects.ProjectsLoaded|100%|| |Orihon.BlazorAdapter.Projects.ProjectWizardEffects|93.8%|90%| |Orihon.BlazorAdapter.Projects.ProjectWizardPage|95.3%|84.1%| |Orihon.BlazorAdapter.Projects.ProjectWizardReducers|100%|| |Orihon.BlazorAdapter.Projects.ProjectWizardState|100%|| |Orihon.BlazorAdapter.Projects.SetupChat|93.5%|100%| |Orihon.BlazorAdapter.Projects.SetupChatEffects|100%|100%| |Orihon.BlazorAdapter.Projects.SetupChatFailed|100%|| |Orihon.BlazorAdapter.Projects.SetupChatReducers|100%|| |Orihon.BlazorAdapter.Projects.SetupChatState|100%|| |Orihon.BlazorAdapter.Projects.SetupChatUpdated|100%|| |Orihon.BlazorAdapter.Projects.StartSetupChat|100%|| |Orihon.BlazorAdapter.Projects.SubmitSetupAnswer|100%|| |Orihon.BlazorAdapter.Projects.WizardDeletePagesRequested|100%|| |Orihon.BlazorAdapter.Projects.WizardLoaded|100%|| |Orihon.BlazorAdapter.Projects.WizardMovePagesRequested|100%|| |Orihon.BlazorAdapter.Projects.WizardMovePagesToNewChapterRequested|100%|| |Orihon.BlazorAdapter.Projects.WizardReorderPagesRequested|100%|| |Orihon.BlazorAdapter.Projects.WizardWriteFailed|100%|| |Orihon.BlazorAdapter.Rulings.AcceptProposalRequested|100%|| |Orihon.BlazorAdapter.Rulings.AnsweredRuling|100%|| |Orihon.BlazorAdapter.Rulings.AnswerRulingRequested|100%|| |Orihon.BlazorAdapter.Rulings.DeclineProposalRequested|100%|| |Orihon.BlazorAdapter.Rulings.DismissRulingRequested|100%|| |Orihon.BlazorAdapter.Rulings.RulingBar|98.2%|94.6%| |Orihon.BlazorAdapter.Rulings.RulingDeskBridge|94.2%|91.6%| |Orihon.BlazorAdapter.Rulings.RulingsEffects|95.4%|83.3%| |Orihon.BlazorAdapter.Rulings.RulingsLoaded|100%|| |Orihon.BlazorAdapter.Rulings.RulingsReducers|100%|| |Orihon.BlazorAdapter.Rulings.RulingsState|100%|| |Orihon.BlazorAdapter.Rulings.RulingWriteFailed|100%|| |Orihon.BlazorAdapter.Rulings.SaveAnswerAsHouseRuleRequested|100%|| |Orihon.BlazorAdapter.Runs.CancelMonitorRun|100%|| |Orihon.BlazorAdapter.Runs.MonitorPageRef|100%|| |Orihon.BlazorAdapter.Runs.MonitorRunLoaded|100%|| |Orihon.BlazorAdapter.Runs.RetryMonitorExecution|100%|| |Orihon.BlazorAdapter.Runs.RunChangedBridge|95%|92.8%| |Orihon.BlazorAdapter.Runs.RunMonitor|98.1%|96.9%| |Orihon.BlazorAdapter.Runs.RunMonitorEffects|100%|91.6%| |Orihon.BlazorAdapter.Runs.RunMonitorReducers|100%|| |Orihon.BlazorAdapter.Runs.RunMonitorState|100%|| |Orihon.BlazorAdapter.Settings.AgentDebriefsLoaded|100%|| |Orihon.BlazorAdapter.Settings.AgentDebriefsLoadFailed|100%|| |Orihon.BlazorAdapter.Settings.AgentEffortPicked|100%|| |Orihon.BlazorAdapter.Settings.AgentEffortSaved|100%|| |Orihon.BlazorAdapter.Settings.AgentEffortSaveFailed|100%|| |Orihon.BlazorAdapter.Settings.AgentFeedbackLoaded|100%|| |Orihon.BlazorAdapter.Settings.AgentFeedbackLoadFailed|0%|| |Orihon.BlazorAdapter.Settings.AgentModelPicked|100%|| |Orihon.BlazorAdapter.Settings.AgentModelSaved|100%|| |Orihon.BlazorAdapter.Settings.AgentModelSaveFailed|100%|| |Orihon.BlazorAdapter.Settings.AgentRoutingPicked|100%|| |Orihon.BlazorAdapter.Settings.AgentRoutingSaved|100%|| |Orihon.BlazorAdapter.Settings.AgentRoutingSaveFailed|0%|| |Orihon.BlazorAdapter.Settings.AgentTranscriptsLoaded|100%|| |Orihon.BlazorAdapter.Settings.AgentTranscriptsLoadFailed|0%|| |Orihon.BlazorAdapter.Settings.CleaningInFlightPicked|100%|| |Orihon.BlazorAdapter.Settings.CleaningInFlightSaveFailed|100%|| |Orihon.BlazorAdapter.Settings.CleaningResumed|100%|| |Orihon.BlazorAdapter.Settings.CleaningRunnerLoaded|100%|| |Orihon.BlazorAdapter.Settings.CleaningServerChecked|100%|| |Orihon.BlazorAdapter.Settings.CleaningServerSaved|100%|| |Orihon.BlazorAdapter.Settings.CleaningServerSaveFailed|100%|| |Orihon.BlazorAdapter.Settings.EffortOption|100%|100%| |Orihon.BlazorAdapter.Settings.FloatingPassToggled|100%|| |Orihon.BlazorAdapter.Settings.KeySaved|100%|| |Orihon.BlazorAdapter.Settings.KeySaveFailed|100%|| |Orihon.BlazorAdapter.Settings.ModelOptionsLoaded|100%|| |Orihon.BlazorAdapter.Settings.ModelOptionsUnavailable|100%|| |Orihon.BlazorAdapter.Settings.ResumeCleaningFailed|100%|| |Orihon.BlazorAdapter.Settings.RoutingOption|100%|100%| |Orihon.BlazorAdapter.Settings.RunConcurrencyPicked|100%|| |Orihon.BlazorAdapter.Settings.RunConcurrencySaveFailed|100%|| |Orihon.BlazorAdapter.Settings.SaveCleaningServerRequested|100%|| |Orihon.BlazorAdapter.Settings.SaveKeyRequested|100%|| |Orihon.BlazorAdapter.Settings.SettingsEffects|92.5%|83.3%| |Orihon.BlazorAdapter.Settings.SettingsLoaded|100%|| |Orihon.BlazorAdapter.Settings.SettingsPage|97.7%|91.6%| |Orihon.BlazorAdapter.Settings.SettingsReducers|96.1%|64.2%| |Orihon.BlazorAdapter.Settings.SettingsState|100%|| |Orihon.BlazorAdapter.Settings.TranscriptFilterPicked|100%|| |Orihon.BlazorAdapter.Settings.TranscriptPagePicked|100%|| |Orihon.BlazorAdapter.Settings.TranscriptPicked|100%|| |Orihon.BlazorAdapter.Settings.TranscriptTextLoaded|100%|| |Orihon.BlazorAdapter.Settings.TranscriptTextLoadFailed|100%|| |Orihon.BlazorAdapter.Uploads.UploadTransfer|96.5%|100%| |Orihon.BlazorAdapter.Uploads.UploadTransferProgress|100%|100%| |Orihon.BlazorAdapter.Uploads.UploadTransferResult|100%|| |Orihon.BlazorAdapter.Workspace.CreateChapterRequested|100%|| |Orihon.BlazorAdapter.Workspace.DeleteChapterRequested|100%|| |Orihon.BlazorAdapter.Workspace.DeletePageRequested|100%|| |Orihon.BlazorAdapter.Workspace.DeleteSummaryRequested|100%|| |Orihon.BlazorAdapter.Workspace.FloatingPassAnswered|100%|| |Orihon.BlazorAdapter.Workspace.LoadProjectWorkspace|100%|| |Orihon.BlazorAdapter.Workspace.MovePageRequested|100%|| |Orihon.BlazorAdapter.Workspace.ProjectMetadataCard|95.6%|92.8%| |Orihon.BlazorAdapter.Workspace.ProjectMetadataSaved|100%|| |Orihon.BlazorAdapter.Workspace.ProjectWorkspaceEffects|100%|100%| |Orihon.BlazorAdapter.Workspace.ProjectWorkspaceLoaded|100%|| |Orihon.BlazorAdapter.Workspace.ProjectWorkspacePage|95.7%|87.9%| |Orihon.BlazorAdapter.Workspace.ProjectWorkspaceReducers|100%|62.5%| |Orihon.BlazorAdapter.Workspace.ProjectWorkspaceState|100%|| |Orihon.BlazorAdapter.Workspace.RenameChapterRequested|100%|| |Orihon.BlazorAdapter.Workspace.ReorderChaptersRequested|100%|| |Orihon.BlazorAdapter.Workspace.ReorderPagesRequested|100%|| |Orihon.BlazorAdapter.Workspace.RunAnnotationRequested|100%|| |Orihon.BlazorAdapter.Workspace.RunBibleRequested|100%|| |Orihon.BlazorAdapter.Workspace.RunFloatingPassRequested|100%|| |Orihon.BlazorAdapter.Workspace.RunTranslationRequested|100%|| |Orihon.BlazorAdapter.Workspace.SaveProjectMetadataRequested|100%|| |Orihon.BlazorAdapter.Workspace.SaveSummaryRequested|100%|| |Orihon.BlazorAdapter.Workspace.SetPageKindRequested|100%|| |Orihon.BlazorAdapter.Workspace.SummaryDeleted|100%|| |Orihon.BlazorAdapter.Workspace.SummarySaved|100%|| |Orihon.BlazorAdapter.Workspace.WorkspaceImportRequested|100%|| |Orihon.BlazorAdapter.Workspace.WorkspaceWriteFailed|100%|| </details> <details><summary>Orihon.Domain - 100%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.Domain**|**100%**|**100%**| |Orihon.Domain.Agents.AgentDebrief|100%|100%| |Orihon.Domain.Agents.AgentDescriptor|100%|| |Orihon.Domain.Agents.AgentFeedback|100%|100%| |Orihon.Domain.Agents.AgentRoster|100%|100%| |Orihon.Domain.Bible.Character|100%|100%| |Orihon.Domain.Bible.GlossaryEntry|100%|100%| |Orihon.Domain.Bible.HouseRule|100%|| |Orihon.Domain.Bible.LoreEntry|100%|100%| |Orihon.Domain.Bible.PageSummary|100%|| |Orihon.Domain.Bible.StoryBeat|100%|| |Orihon.Domain.Bible.StoryOverview|100%|| |Orihon.Domain.Cleaning.CleaningCall|100%|100%| |Orihon.Domain.Cleaning.CleaningCallRect|100%|| |Orihon.Domain.Cleaning.CleaningCanvas|100%|| |Orihon.Domain.Cleaning.CleaningOutput|100%|100%| |Orihon.Domain.Cleaning.CleaningServerIdentity|100%|| |Orihon.Domain.Cleaning.CleaningServerState|100%|100%| |Orihon.Domain.Cleaning.CleaningWindow|100%|| |Orihon.Domain.Projects.Project|100%|100%| |Orihon.Domain.Projects.ProjectProfile|100%|| |Orihon.Domain.Runs.Execution|100%|100%| |Orihon.Domain.Runs.RegionProblem|100%|| |Orihon.Domain.Runs.Run|100%|| |Orihon.Domain.Settings.AppSetting|100%|| |Orihon.Domain.Text|100%|100%| |Orihon.Domain.Translation.BoundingBox|100%|100%| |Orihon.Domain.Translation.Chapter|100%|| |Orihon.Domain.Translation.InkColor|100%|100%| |Orihon.Domain.Translation.Page|100%|| |Orihon.Domain.Translation.Region|100%|100%| |Orihon.Domain.Translation.RegionInk|100%|100%| |Orihon.Domain.Translation.RegionProfile|100%|| </details> <details><summary>Orihon.Infrastructure - 97.5%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.Infrastructure**|**97.5%**|**83.3%**| |Orihon.Infrastructure.Agents.EfAgentDebriefStore|100%|| |Orihon.Infrastructure.Agents.EfAgentFeedbackStore|100%|| |Orihon.Infrastructure.Bible.EfBibleStore|95.2%|92.8%| |Orihon.Infrastructure.Cleaning.EfCleaningCallStore|98.6%|100%| |Orihon.Infrastructure.DependencyInjection|100%|100%| |Orihon.Infrastructure.Gateways.AgentToolAdapter|100%|| |Orihon.Infrastructure.Gateways.AgentToolAdapter`1|100%|100%| |Orihon.Infrastructure.Gateways.AgentTranscript|95.6%|89%| |Orihon.Infrastructure.Gateways.Cleaning.BoxChecks|100%|100%| |Orihon.Infrastructure.Gateways.Cleaning.DerivedInk|100%|| |Orihon.Infrastructure.Gateways.Cleaning.FillResult|100%|| |Orihon.Infrastructure.Gateways.Cleaning.GateStats|100%|| |Orihon.Infrastructure.Gateways.Cleaning.GreyRule|100%|100%| |Orihon.Infrastructure.Gateways.Cleaning.LabFill|100%|100%| |Orihon.Infrastructure.Gateways.Cleaning.LabInk|100%|98.3%| |Orihon.Infrastructure.Gateways.Cleaning.LabPaper|100%|97.3%| |Orihon.Infrastructure.Gateways.Cleaning.PaperComponent|100%|| |Orihon.Infrastructure.Gateways.Cleaning.RasterCleaningImages|100%|100%| |Orihon.Infrastructure.Gateways.Cleaning.RasterInkAnalyzer|100%|100%| |Orihon.Infrastructure.Gateways.Cleaning.Rgb|100%|| |Orihon.Infrastructure.Gateways.FileSystemAgentTranscriptStore|85.2%|80.8%| |Orihon.Infrastructure.Gateways.HttpWebPageFetcher|95.1%|83.3%| |Orihon.Infrastructure.Gateways.LabelFont|100%|50%| |Orihon.Infrastructure.Gateways.OpenRouterLlmGateway|90.2%|82.1%| |Orihon.Infrastructure.Gateways.QwenImageServerGateway|96.7%|90%| |Orihon.Infrastructure.Gateways.QwenImageServerJson|96%|72.3%| |Orihon.Infrastructure.Gateways.Raster.FloatImage|66.6%|50%| |Orihon.Infrastructure.Gateways.Raster.GrayImage|87.5%|75%| |Orihon.Infrastructure.Gateways.Raster.Labels|100%|100%| |Orihon.Infrastructure.Gateways.Raster.Mask|95.6%|92.6%| |Orihon.Infrastructure.Gateways.Raster.NumpyMath|93.9%|93.4%| |Orihon.Infrastructure.Gateways.Raster.PillowBlur|98.4%|89.4%| |Orihon.Infrastructure.Gateways.Raster.PillowLanczos|100%|100%| |Orihon.Infrastructure.Gateways.Raster.PixelBox|100%|100%| |Orihon.Infrastructure.Gateways.Raster.RgbImage|96.4%|75%| |Orihon.Infrastructure.Gateways.Raster.ScipyGaussian|100%|100%| |Orihon.Infrastructure.Gateways.SkiaImages|100%|100%| |Orihon.Infrastructure.Gateways.SkiaPageImageRenderer|97.4%|90.8%| |Orihon.Infrastructure.Gateways.SkiaPixelDigest|100%|100%| |Orihon.Infrastructure.Gateways.SkiaRegionColorSampler|100%|100%| |Orihon.Infrastructure.Gateways.UntaggedPng|100%|100%| |Orihon.Infrastructure.Persistence.Configurations.AgentDebriefConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.AgentFeedbackConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.AppSettingConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.ChapterConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.CharacterConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.CleaningCallConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.CleaningOutputConfiguratio<br/>n|100%|| |Orihon.Infrastructure.Persistence.Configurations.CleaningServerStateConfigu<br/>ration|100%|| |Orihon.Infrastructure.Persistence.Configurations.ExecutionConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.GlossaryEntryConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.HouseRuleConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.JsonColumnMapper|100%|| |Orihon.Infrastructure.Persistence.Configurations.LoreEntryConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.PageConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.PageSummaryConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.ProjectConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.RegionConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.RunConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.StoryBeatConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.StoryOverviewConfiguration|100%|| |Orihon.Infrastructure.Persistence.Converters.UtcTicksConverter|100%|| |Orihon.Infrastructure.Persistence.Migrations.AddAgentDebriefs|99.5%|| |Orihon.Infrastructure.Persistence.Migrations.AddAgentFeedback|99.5%|| |Orihon.Infrastructure.Persistence.Migrations.AddAppSettings|99.3%|| |Orihon.Infrastructure.Persistence.Migrations.AddCleaningCallRunner|99.3%|| |Orihon.Infrastructure.Persistence.Migrations.AddExecutionFeedbackRegions|99.3%|| |Orihon.Infrastructure.Persistence.Migrations.AddHouseRules|99.6%|| |Orihon.Infrastructure.Persistence.Migrations.AddPagePassFacts|99%|| |Orihon.Infrastructure.Persistence.Migrations.AddProjectSourceLanguage|99.3%|| |Orihon.Infrastructure.Persistence.Migrations.AddRegionFitBoxDropFillHints|98.1%|| |Orihon.Infrastructure.Persistence.Migrations.AddRegionForm|99.4%|| |Orihon.Infrastructure.Persistence.Migrations.AddRegionInk|99.4%|| |Orihon.Infrastructure.Persistence.Migrations.AddRuns|99.1%|| |Orihon.Infrastructure.Persistence.Migrations.AddStoryOverview|99.5%|| |Orihon.Infrastructure.Persistence.Migrations.DropRegionContainer|99.1%|| |Orihon.Infrastructure.Persistence.Migrations.DropRegionType|99%|| |Orihon.Infrastructure.Persistence.Migrations.InitialTranslationDomain|97.3%|| |Orihon.Infrastructure.Persistence.Migrations.OrihonDbContextModelSnapshot|100%|| |Orihon.Infrastructure.Persistence.Migrations.RenameSourceTargetColumns|97.2%|| |Orihon.Infrastructure.Persistence.Migrations.ReplaceFitBoxWithContainerSeed|99.2%|| |Orihon.Infrastructure.Persistence.OrihonDbContext|100%|| |Orihon.Infrastructure.Persistence.OrihonDbContextFactory|100%|| |Orihon.Infrastructure.Projects.EfProjectStore|100%|100%| |Orihon.Infrastructure.Projects.FileSystemPageImageStore|100%|100%| |Orihon.Infrastructure.Runs.EfRunStore|98.2%|75%| |Orihon.Infrastructure.Settings.EfAppSettingsStore|100%|100%| |Orihon.Infrastructure.Translation.EfChapterStore|100%|100%| |Orihon.Infrastructure.Translation.EfPageStore|98.3%|93.7%| |Orihon.Infrastructure.Translation.EfRegionStore|100%|100%| |Orihon.Infrastructure.Translation.Ordering|100%|100%| |System.Text.RegularExpressions.Generated|70.6%|53.3%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030<br/>A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlankLines_4|77.9%|76.6%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030<br/>A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlockBreaks_1|59%|42.5%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030<br/>A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__SpaceRuns_3|89.4%|75%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030<br/>A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__Tags_2|83.7%|62.5%| </details> <details><summary>Orihon.Kernel - 90.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.Kernel**|**90.9%**|**75%**| |Orihon.Kernel.Err`1|100%|| |Orihon.Kernel.Ok`1|100%|| |Orihon.Kernel.Result`1|88.8%|75%| </details> <details><summary>Orihon.Server - 94.6%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.Server**|**94.6%**|**79.4%**| |Orihon.Server.CleaningCallRunnerBootstrap|100%|| |Orihon.Server.Components.App|100%|| |Orihon.Server.Components.Layout.MainLayout|100%|| |Orihon.Server.Components.Pages.Gate|64.2%|66.6%| |Orihon.Server.Diagnostics.FakeCleaningServer|94.6%|80.7%| |Orihon.Server.RunEngineBootstrap|100%|| |Orihon.Server.Security.AccessGate|91.8%|41.6%| |Orihon.Server.Security.AccessSecret|100%|50%| |Orihon.Server.VolumeStartupValidator|100%|100%| |Program|95.7%|85.7%| </details> <details><summary>Orihon.UseCases - 97.6%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.UseCases**|**97.6%**|**90.9%**| |Orihon.UseCases.Agents.AgentAttemptPreparation|100%|| |Orihon.UseCases.Agents.AgentAttemptSupport|98.6%|98.3%| |Orihon.UseCases.Agents.AgentBlueprint|100%|| |Orihon.UseCases.Agents.AgentCapDebrief|100%|| |Orihon.UseCases.Agents.AgentInvocation|100%|| |Orihon.UseCases.Agents.AgentOutcome|100%|| |Orihon.UseCases.Agents.AgentTool`1|90.9%|75%| |Orihon.UseCases.Agents.AgentToolImage|100%|| |Orihon.UseCases.Agents.AgentToolResult|100%|| |Orihon.UseCases.Agents.Annotation.AddFloatingRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.AddFloatingRegionTool|95.8%|75%| |Orihon.UseCases.Agents.Annotation.AddRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.AddRegionTool|95.4%|75%| |Orihon.UseCases.Agents.Annotation.AnnotationBlueprints|100%|| |Orihon.UseCases.Agents.Annotation.AnnotationStage|100%|86.1%| |Orihon.UseCases.Agents.Annotation.BboxCreationExecutor|90.4%|50%| |Orihon.UseCases.Agents.Annotation.BboxRefinementExecutor|96.5%|90%| |Orihon.UseCases.Agents.Annotation.BoundBoxParams|100%|| |Orihon.UseCases.Agents.Annotation.BoundContactSheetTool|91.3%|75%| |Orihon.UseCases.Agents.Annotation.BoundCropParams|100%|| |Orihon.UseCases.Agents.Annotation.BoundCropTool|100%|| |Orihon.UseCases.Agents.Annotation.BoundViewPageTool|93.1%|80%| |Orihon.UseCases.Agents.Annotation.BoundViewParams|100%|| |Orihon.UseCases.Agents.Annotation.ClassifyRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.ClassifyRegionTool|100%|100%| |Orihon.UseCases.Agents.Annotation.ColorReading|100%|100%| |Orihon.UseCases.Agents.Annotation.DeleteBoundRegionTool|100%|100%| |Orihon.UseCases.Agents.Annotation.DeleteRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.DeleteRegionTool|100%|100%| |Orihon.UseCases.Agents.Annotation.FindGlossaryParams|100%|| |Orihon.UseCases.Agents.Annotation.FindGlossaryTool|88.2%|62.5%| |Orihon.UseCases.Agents.Annotation.FloatingCreationExecutor|86.9%|50%| |Orihon.UseCases.Agents.Annotation.FloatingQaExecutor|91.8%|78.5%| |Orihon.UseCases.Agents.Annotation.FloatingTranscriptionExecutor|95.4%|75%| |Orihon.UseCases.Agents.Annotation.ListRegionsTool|93.7%|80.7%| |Orihon.UseCases.Agents.Annotation.MoveResizeBoundTool|90.9%|50%| |Orihon.UseCases.Agents.Annotation.MoveResizeRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.MoveResizeRegionTool|95.8%|83.3%| |Orihon.UseCases.Agents.Annotation.NoteRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.NoteRegionTool|100%|100%| |Orihon.UseCases.Agents.Annotation.PageQaExecutor|92.5%|79.1%| |Orihon.UseCases.Agents.Annotation.QaReportSink|100%|100%| |Orihon.UseCases.Agents.Annotation.RegionAuthoringAccess|89.4%|62.5%| |Orihon.UseCases.Agents.Annotation.RegionBriefing|100%|96.1%| |Orihon.UseCases.Agents.Annotation.RegionCropParams|100%|| |Orihon.UseCases.Agents.Annotation.RegionCropTool|100%|100%| |Orihon.UseCases.Agents.Annotation.RegionProblemParams|100%|| |Orihon.UseCases.Agents.Annotation.RegionWindow|100%|100%| |Orihon.UseCases.Agents.Annotation.RejectRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.RejectRegionTool|100%|100%| |Orihon.UseCases.Agents.Annotation.ReorderRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.ReorderRegionTool|88%|60%| |Orihon.UseCases.Agents.Annotation.ReportQaParams|100%|| |Orihon.UseCases.Agents.Annotation.ReportQaTool|97.8%|90%| |Orihon.UseCases.Agents.Annotation.SampleColorsParams|100%|| |Orihon.UseCases.Agents.Annotation.SampleColorsTool|100%|100%| |Orihon.UseCases.Agents.Annotation.SampleRegionColorsParams|100%|| |Orihon.UseCases.Agents.Annotation.SampleRegionColorsTool|100%|100%| |Orihon.UseCases.Agents.Annotation.SetInkParams|100%|| |Orihon.UseCases.Agents.Annotation.SetInkTool|100%|100%| |Orihon.UseCases.Agents.Annotation.SetPageMetaParams|100%|| |Orihon.UseCases.Agents.Annotation.SetPageMetaTool|100%|75%| |Orihon.UseCases.Agents.Annotation.SetRegionInkParams|100%|| |Orihon.UseCases.Agents.Annotation.SetRegionInkTool|100%|100%| |Orihon.UseCases.Agents.Annotation.SetTranscriptionParams|100%|| |Orihon.UseCases.Agents.Annotation.SetTranscriptionTool|100%|100%| |Orihon.UseCases.Agents.Annotation.TranscriptionExecutor|97.7%|94.4%| |Orihon.UseCases.Agents.AssistantSpoke|100%|| |Orihon.UseCases.Agents.BibleBuilding.BibleBuildingBlueprint|100%|| |Orihon.UseCases.Agents.BibleBuilding.BibleBuildingExecutor|96.9%|75%| |Orihon.UseCases.Agents.BibleBuilding.GetRegionParams|100%|| |Orihon.UseCases.Agents.BibleBuilding.GetRegionTool|84.6%|70%| |Orihon.UseCases.Agents.BibleBuilding.ListProjectRegionsTool|86.3%|83.3%| |Orihon.UseCases.Agents.BibleBuilding.ListRegionsParams|100%|| |Orihon.UseCases.Agents.Inspection.PageImageAccess|95.2%|80.6%| |Orihon.UseCases.Agents.Inspection.ViewAccount|100%|100%| |Orihon.UseCases.Agents.ReportFrictionParams|100%|| |Orihon.UseCases.Agents.ReportFrictionTool|100%|92.8%| |Orihon.UseCases.Agents.ResearchSetup.AddStoryBeatParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.AddStoryBeatTool|100%|75%| |Orihon.UseCases.Agents.ResearchSetup.AskUserParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.AskUserTool|100%|100%| |Orihon.UseCases.Agents.ResearchSetup.DeleteStoryBeatParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.DeleteStoryBeatTool|100%|100%| |Orihon.UseCases.Agents.ResearchSetup.FetchUrlParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.FetchUrlTool|100%|100%| |Orihon.UseCases.Agents.ResearchSetup.ListBibleTool|90.3%|66.6%| |Orihon.UseCases.Agents.ResearchSetup.ListPagesTool|97%|83.3%| |Orihon.UseCases.Agents.ResearchSetup.LocatedPage|100%|| |Orihon.UseCases.Agents.ResearchSetup.PageByNumber|95%|91.6%| |Orihon.UseCases.Agents.ResearchSetup.ResearchSetupBlueprint|100%|| |Orihon.UseCases.Agents.ResearchSetup.SetPageMetaParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.SetPageMetaTool|95.2%|90%| |Orihon.UseCases.Agents.ResearchSetup.SetPageSummaryParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.SetPageSummaryTool|95.8%|75%| |Orihon.UseCases.Agents.ResearchSetup.SetProjectMetadataParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.SetProjectMetadataTool|96.5%|95.8%| |Orihon.UseCases.Agents.ResearchSetup.SetStoryOverviewParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.SetStoryOverviewTool|100%|100%| |Orihon.UseCases.Agents.ResearchSetup.StoryBeatByNumber|100%|100%| |Orihon.UseCases.Agents.ResearchSetup.UpdateStoryBeatParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.UpdateStoryBeatTool|100%|75%| |Orihon.UseCases.Agents.ResearchSetup.UpsertCharacterParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.UpsertCharacterTool|92.3%|71.4%| |Orihon.UseCases.Agents.ResearchSetup.UpsertGlossaryParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.UpsertGlossaryTool|97.4%|90%| |Orihon.UseCases.Agents.ResearchSetup.UpsertLoreParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.UpsertLoreTool|92.3%|71.4%| |Orihon.UseCases.Agents.ResearchSetup.ViewPageParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.ViewPageTool|100%|100%| |Orihon.UseCases.Agents.RoundStarted|100%|| |Orihon.UseCases.Agents.Rulings.AnswerRuling|100%|| |Orihon.UseCases.Agents.Rulings.DismissRuling|100%|| |Orihon.UseCases.Agents.Rulings.HouseRuleProposal|100%|| |Orihon.UseCases.Agents.Rulings.ListPendingRulings|100%|| |Orihon.UseCases.Agents.Rulings.ListRuleProposals|100%|| |Orihon.UseCases.Agents.Rulings.PendingRuling|100%|| |Orihon.UseCases.Agents.Rulings.ProposeHouseRuleParams|100%|| |Orihon.UseCases.Agents.Rulings.ProposeHouseRuleTool|100%|100%| |Orihon.UseCases.Agents.Rulings.RequestRulingParams|100%|| |Orihon.UseCases.Agents.Rulings.RequestRulingTool|100%|81.2%| |Orihon.UseCases.Agents.Rulings.RulingAnswer|100%|| |Orihon.UseCases.Agents.Rulings.RulingDesk|97.8%|80%| |Orihon.UseCases.Agents.Rulings.RulingOption|100%|| |Orihon.UseCases.Agents.Rulings.RulingOptionParams|100%|| |Orihon.UseCases.Agents.Rulings.SettledRuling|100%|| |Orihon.UseCases.Agents.Rulings.WithdrawRuleProposal|100%|| |Orihon.UseCases.Agents.Setup.ResearchSetupExecutor|98.5%|92.8%| |Orihon.UseCases.Agents.Setup.SetupChatEntry|100%|| |Orihon.UseCases.Agents.Setup.SetupConversation|100%|87.5%| |Orihon.UseCases.Agents.Setup.SetupConversationRegistry|100%|| |Orihon.UseCases.Agents.ToolCalled|100%|| |Orihon.UseCases.Agents.ToolCompleted|100%|| |Orihon.UseCases.Agents.TranscriptLabel|100%|100%| |Orihon.UseCases.Agents.Translation.GetPageSummaryParams|100%|| |Orihon.UseCases.Agents.Translation.GetPageSummaryTool|80%|66.6%| |Orihon.UseCases.Agents.Translation.SetTranslationParams|100%|| |Orihon.UseCases.Agents.Translation.SetTranslationTool|88.5%|78.5%| |Orihon.UseCases.Agents.Translation.TranslationBlueprint|100%|| |Orihon.UseCases.Agents.Translation.TranslationExecutor|93.8%|71.4%| |Orihon.UseCases.Agents.Translation.UpdateGlossaryEnParams|100%|| |Orihon.UseCases.Agents.Translation.UpdateGlossaryEnTool|82.6%|62.5%| |Orihon.UseCases.Bible.AddCharacter|100%|100%| |Orihon.UseCases.Bible.AddGlossaryEntry|100%|100%| |Orihon.UseCases.Bible.AddHouseRule|100%|100%| |Orihon.UseCases.Bible.AddLoreEntry|100%|100%| |Orihon.UseCases.Bible.AddStoryBeat|100%|100%| |Orihon.UseCases.Bible.BibleDto|100%|| |Orihon.UseCases.Bible.CharacterDto|100%|| |Orihon.UseCases.Bible.DeleteCharacter|100%|100%| |Orihon.UseCases.Bible.DeleteGlossaryEntry|100%|100%| |Orihon.UseCases.Bible.DeleteHouseRule|100%|100%| |Orihon.UseCases.Bible.DeleteLoreEntry|100%|100%| |Orihon.UseCases.Bible.DeletePageSummary|100%|100%| |Orihon.UseCases.Bible.DeleteStoryBeat|100%|100%| |Orihon.UseCases.Bible.GetBible|100%|100%| |Orihon.UseCases.Bible.GlossaryEntryDto|100%|| |Orihon.UseCases.Bible.HouseRuleDto|100%|| |Orihon.UseCases.Bible.LoreEntryDto|100%|| |Orihon.UseCases.Bible.PageSummaryDto|100%|| |Orihon.UseCases.Bible.ReorderStoryBeats|100%|| |Orihon.UseCases.Bible.SetPageSummary|100%|100%| |Orihon.UseCases.Bible.SetStoryOverview|100%|100%| |Orihon.UseCases.Bible.StoryBeatDto|100%|| |Orihon.UseCases.Bible.StoryOverviewDto|100%|| |Orihon.UseCases.Bible.UpdateCharacter|100%|100%| |Orihon.UseCases.Bible.UpdateGlossaryEntry|100%|100%| |Orihon.UseCases.Bible.UpdateHouseRule|100%|100%| |Orihon.UseCases.Bible.UpdateLoreEntry|100%|100%| |Orihon.UseCases.Bible.UpdateStoryBeat|100%|100%| |Orihon.UseCases.Chapters.ChapterDto|100%|| |Orihon.UseCases.Chapters.CreateChapter|100%|100%| |Orihon.UseCases.Chapters.DeleteChapter|100%|100%| |Orihon.UseCases.Chapters.RenameChapter|100%|100%| |Orihon.UseCases.Chapters.ReorderChapters|100%|| |Orihon.UseCases.Cleaning.CanaryShape|100%|50%| |Orihon.UseCases.Cleaning.CleaningCacheKey|100%|100%| |Orihon.UseCases.Cleaning.CleaningCallFailed|100%|| |Orihon.UseCases.Cleaning.CleaningCallHalted|100%|| |Orihon.UseCases.Cleaning.CleaningCallRequest|100%|| |Orihon.UseCases.Cleaning.CleaningCallReturned|100%|| |Orihon.UseCases.Cleaning.CleaningCallRunner|97.1%|95.1%| |Orihon.UseCases.Cleaning.CleaningCanary|100%|| |Orihon.UseCases.Cleaning.CleaningCandidate|80%|| |Orihon.UseCases.Cleaning.CleaningFailure|100%|| |Orihon.UseCases.Cleaning.CleaningFailures|100%|97.6%| |Orihon.UseCases.Cleaning.CleaningGpuTime|100%|| |Orihon.UseCases.Cleaning.CleaningHealth|100%|100%| |Orihon.UseCases.Cleaning.CleaningIdentity|100%|89.7%| |Orihon.UseCases.Cleaning.CleaningRecipe|100%|| |Orihon.UseCases.Cleaning.CleaningRunnerOptions|100%|| |Orihon.UseCases.Cleaning.CleaningRunnerStatus|100%|| |Orihon.UseCases.Cleaning.GetCleaningRunnerStatus|100%|| |Orihon.UseCases.Cleaning.GpuWait|100%|| |Orihon.UseCases.Cleaning.JobClock|100%|100%| |Orihon.UseCases.Cleaning.JobIdentity|100%|| |Orihon.UseCases.Cleaning.ResumeCleaning|100%|100%| |Orihon.UseCases.Cleaning.UploadNotes|100%|| |Orihon.UseCases.Debriefs.AgentDebriefDto|90.9%|| |Orihon.UseCases.Debriefs.AgentFeedbackDto|83.3%|| |Orihon.UseCases.Debriefs.ClearAgentDebriefs|100%|| |Orihon.UseCases.Debriefs.ClearAgentFeedback|100%|| |Orihon.UseCases.Debriefs.ListAgentDebriefs|100%|100%| |Orihon.UseCases.Debriefs.ListAgentFeedback|100%|75%| |Orihon.UseCases.DependencyInjection|100%|| |Orihon.UseCases.Diagnostics.FakeCleaningServerAddress|100%|| |Orihon.UseCases.Diagnostics.SeedDevData|99.2%|82.1%| |Orihon.UseCases.Gateways.BoxFlag|100%|| |Orihon.UseCases.Gateways.ClosedBalloon|100%|| |Orihon.UseCases.Gateways.ColorShare|100%|| |Orihon.UseCases.Gateways.EditBackendError|100%|| |Orihon.UseCases.Gateways.EditBackendIdentity|100%|| |Orihon.UseCases.Gateways.EditJob|100%|| |Orihon.UseCases.Gateways.EditJobAccepted|100%|| |Orihon.UseCases.Gateways.EditJobRejected|100%|| |Orihon.UseCases.Gateways.EditJobRequest|86.6%|66.6%| |Orihon.UseCases.Gateways.EditJobRun|100%|| |Orihon.UseCases.Gateways.EditModels|100%|| |Orihon.UseCases.Gateways.EditModelWeight|100%|| |Orihon.UseCases.Gateways.EditOutputImage|100%|| |Orihon.UseCases.Gateways.EditOutputWithheld|100%|| |Orihon.UseCases.Gateways.EditRect|100%|100%| |Orihon.UseCases.Gateways.EditRunOutput|100%|| |Orihon.UseCases.Gateways.EditServerAnswered`1|100%|| |Orihon.UseCases.Gateways.EditServerBuild|100%|| |Orihon.UseCases.Gateways.EditServerHealth|100%|| |Orihon.UseCases.Gateways.EditServerSilent`1|100%|| |Orihon.UseCases.Gateways.FillRefusal|100%|| |Orihon.UseCases.Gateways.FillReport|100%|| |Orihon.UseCases.Gateways.GlyphFill|100%|| |Orihon.UseCases.Gateways.GridAxis|100%|| |Orihon.UseCases.Gateways.GridSteps|100%|| |Orihon.UseCases.Gateways.InkFacts|100%|| |Orihon.UseCases.Gateways.InkRegion|100%|| |Orihon.UseCases.Gateways.LabeledBox|100%|| |Orihon.UseCases.Gateways.LlmKeyInfo|100%|| |Orihon.UseCases.Gateways.LlmModel|100%|| |Orihon.UseCases.Gateways.LlmReasoning|100%|100%| |Orihon.UseCases.Gateways.PageTone|100%|| |Orihon.UseCases.Gateways.PaperColor|100%|| |Orihon.UseCases.Gateways.PixelDigest|100%|| |Orihon.UseCases.Gateways.PixelMask|100%|| |Orihon.UseCases.Gateways.PixelRect|100%|| |Orihon.UseCases.Gateways.PixelWindow|100%|| |Orihon.UseCases.Gateways.RenderedView|100%|| |Orihon.UseCases.Gateways.StoredTranscript|100%|| |Orihon.UseCases.Gateways.StoredTranscriptPage|100%|| |Orihon.UseCases.Gateways.TranscriptHeader|97.3%|90.9%| |Orihon.UseCases.Gateways.TranscriptListingFacets|100%|| |Orihon.UseCases.Gateways.TranscriptSummary|100%|| |Orihon.UseCases.Gateways.WindowUpload|100%|| |Orihon.UseCases.NextOrder|100%|| |Orihon.UseCases.Pages.DeletePage|100%|100%| |Orihon.UseCases.Pages.DeletePages|100%|100%| |Orihon.UseCases.Pages.GetPage|100%|100%| |Orihon.UseCases.Pages.GetPageSteps|100%|100%| |Orihon.UseCases.Pages.GetProjectWorkspace|100%|100%| |Orihon.UseCases.Pages.ImportPages|100%|100%| |Orihon.UseCases.Pages.ImportPagesResult|100%|| |Orihon.UseCases.Pages.MarkPageAnnotated|100%|100%| |Orihon.UseCases.Pages.MarkPagePasses|100%|50%| |Orihon.UseCases.Pages.MovePage|100%|93.7%| |Orihon.UseCases.Pages.MovePages|100%|100%| |Orihon.UseCases.Pages.PageDetailDto|100%|| |Orihon.UseCases.Pages.PageDto|100%|| |Orihon.UseCases.Pages.PageStepsDto|100%|| |Orihon.UseCases.Pages.PageUpload|100%|| |Orihon.UseCases.Pages.ProjectWorkspaceDto|100%|| |Orihon.UseCases.Pages.ReorderPages|100%|| |Orihon.UseCases.Pages.SetPageMeta|100%|100%| |Orihon.UseCases.Pages.WorkspaceChapterDto|100%|| |Orihon.UseCases.Projects.CompleteProjectSetup|100%|93.7%| |Orihon.UseCases.Projects.CreateProject|100%|100%| |Orihon.UseCases.Projects.DeleteProject|100%|100%| |Orihon.UseCases.Projects.FloatingPassAnswer|100%|| |Orihon.UseCases.Projects.GetProject|100%|100%| |Orihon.UseCases.Projects.ListProjects|100%|| |Orihon.UseCases.Projects.PageMention|100%|| |Orihon.UseCases.Projects.ProjectDto|96.1%|| |Orihon.UseCases.Projects.StartAnnotationRun|96.5%|92.8%| |Orihon.UseCases.Projects.StartBibleRun|92.3%|83.3%| |Orihon.UseCases.Projects.StartFloatingPassRun|100%|100%| |Orihon.UseCases.Projects.StartSetupRun|100%|100%| |Orihon.UseCases.Projects.StartTranslationRun|92.3%|83.3%| |Orihon.UseCases.Projects.StoredPageImage|100%|| |Orihon.UseCases.Projects.UpdateProjectMetadata|100%|100%| |Orihon.UseCases.Regions.CreateRegion|100%|100%| |Orihon.UseCases.Regions.DeleteRegion|100%|100%| |Orihon.UseCases.Regions.RegionDto|96.8%|| |Orihon.UseCases.Regions.ReorderRegions|100%|| |Orihon.UseCases.Regions.SampleRegionColors|100%|50%| |Orihon.UseCases.Regions.UpdateRegion|100%|100%| |Orihon.UseCases.Runs.AnnotationPipeline|100%|100%| |Orihon.UseCases.Runs.AttemptLedger|100%|100%| |Orihon.UseCases.Runs.ExecutionDto|93.3%|| |Orihon.UseCases.Runs.ExecutionProgress|100%|| |Orihon.UseCases.Runs.ExecutionProgressRegistry|100%|100%| |Orihon.UseCases.Runs.ExecutionPulseRelay|100%|100%| |Orihon.UseCases.Runs.ExecutionSendBack|100%|| |Orihon.UseCases.Runs.PlannedExecution|100%|| |Orihon.UseCases.Runs.PulseTarget|100%|| |Orihon.UseCases.Runs.ReprocessPage|97%|95.8%| |Orihon.UseCases.Runs.ReprocessTranslation|88.8%|83.3%| |Orihon.UseCases.Runs.RunDto|93.3%|90%| |Orihon.UseCases.Runs.RunEngine|95.8%|94%| |Orihon.UseCases.Runs.RunEngineOptions|100%|100%| |Orihon.UseCases.Runs.RunPhase|94.1%|100%| |Orihon.UseCases.Runs.RunStart|100%|| |Orihon.UseCases.Runs.StageContext|100%|50%| |Orihon.UseCases.Runs.StageHaltedException|100%|| |Orihon.UseCases.Runs.WorkStates|100%|83.3%| |Orihon.UseCases.Settings.AgentSettingDto|100%|100%| |Orihon.UseCases.Settings.CheckCleaningServer|87.5%|60%| |Orihon.UseCases.Settings.CleaningInFlightSetting|100%|100%| |Orihon.UseCases.Settings.CleaningServerSetting|100%|100%| |Orihon.UseCases.Settings.CleaningServerStatusDto|100%|100%| |Orihon.UseCases.Settings.ConcurrencySetting|100%|100%| |Orihon.UseCases.Settings.EffortSetting|100%|100%| |Orihon.UseCases.Settings.GetSettings|100%|100%| |Orihon.UseCases.Settings.ListModelOptions|100%|100%| |Orihon.UseCases.Settings.RoutingSetting|100%|100%| |Orihon.UseCases.Settings.SaveAgentEffort|100%|100%| |Orihon.UseCases.Settings.SaveAgentModel|100%|100%| |Orihon.UseCases.Settings.SaveAgentRouting|100%|100%| |Orihon.UseCases.Settings.SaveCleaningInFlight|100%|100%| |Orihon.UseCases.Settings.SaveCleaningServer|95.2%|85.7%| |Orihon.UseCases.Settings.SaveFloatingPass|100%|100%| |Orihon.UseCases.Settings.SaveOpenRouterKey|100%|100%| |Orihon.UseCases.Settings.SaveRunConcurrency|100%|100%| |Orihon.UseCases.Settings.SettingKeys|100%|100%| |Orihon.UseCases.Settings.SettingsDto|100%|100%| |Orihon.UseCases.Transcripts.AgentTranscriptDto|100%|| |Orihon.UseCases.Transcripts.AgentTranscriptListDto|100%|| |Orihon.UseCases.Transcripts.AgentTranscriptPageDto|100%|| |Orihon.UseCases.Transcripts.AgentTranscriptTextDto|100%|| |Orihon.UseCases.Transcripts.ClearAgentTranscripts|100%|100%| |Orihon.UseCases.Transcripts.ListAgentTranscripts|100%|100%| |Orihon.UseCases.Transcripts.ReadAgentTranscript|100%|100%| </details>
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! Eleven and a half thousand lines, one hundred files — a whole organ system! The call runner, the trouble clock, the breaker, the canary... I read every line of the runner twice, darling, and I compared it against its siblings (RunEngine, the EF stores, the page ops). This is the most carefully built state machine I've seen in this repository~ ♡

Verdict: ✅ Looks good to me~

🔬 Mutation probes — all three killed, zero survived

I didn't trust the green checkmark alone, so I bent the code myself:

  1. CleaningIdentity.Check per-output known-selector — dropped the resumed_after and per-output build guards (leaving only jobKnown). → 3 tests failed (What_the_check_cannot_confirm... × 3, incl. outputs below resumed_after and an output it does not name). The identity selector is pinned.
  2. PollAsync 35 s recheck window — doubled recheckAt to Recheck + Recheck. → An_outage_that_may_just_have_healed_is_read_again_after_35_seconds failed (line 575 InRange assertion). The healing-outage re-judgement is pinned.
  3. RunCallAsync cache-key seed offset — keyed every output at call.Seed instead of call.Seed + i. → 4 tests failed (cache serve, cross-page serve, replay seeds, ...). The s+i replay contract is pinned. ♪

All reverted; the worktree is clean. You survived my probes without a scratch~

✅ What I liked~

  • The domain guards. CleaningCall's Require(params CleaningCallStatus[]) transitions and the canary/page invariant in the constructor made me genuinely giddy. State machines that refuse to lie~ ♡
  • CleaningCallRunnerBootstrap ordering. Registered before RunEngineBootstrap so a requeued attempt finds its job in flight and never resubmits — and DependencyInjectionTests pins ICleaningJobHolds resolving to the same singleton. Delicious.
  • The tallies. Tally(repeats, requestKey, callId) counting a shared job's failure once against the call, however many callers it answered — exactly the fail-once contract, and probed-arm tests cover both one-job-two-callers and the halt on repeat.
  • Atomic call files (WriteCallFileAsync partial-then-move, plus the path-traversal guard in CallPath), the FK cascade with plain-id execution/invocation, the indexed CacheKey — the persistence story is airtight.
  • Test infrastructure quality. ScriptedEditServer replaying the lab's traces.json, RunnerHarness on a FakeTimeProvider, and CleaningFailuresTests covering every classification row including presubmit >= 8 half-up. This suite doesn't just compile, it guards.
  • The honest notes section. Naming the build-identity judgment call and inviting overturn — that's how ADR amendments should be done.

💡 Little ideas (non-blocking)~

  1. CleaningCallRunner.cs:1095 — WriteCallFilesAsync(saved, [], token) rewrites call.json with zero files after every finish; a comment there noting it's the "rewrite the record beside the outputs" step (its doc says so, the call site reads a little like a no-op) would spare the next reader a double-take.
  2. CleaningCallRunner.cs:966-970 — the Observed persistence is skipped unless RunningSince presence flips; a tiny comment explaining "only stint boundaries are written, not every poll" would make the write-amplification choice explicit.
  3. gen_canary.py / gen_digest_oracle.py — lovely committed generators; consider naming the Python version that produced each committed PNG in the file header so a future regeneration is auditable.

Nothing blocking. The breaker, the canary, the clock, the slots — all correct as far as I can bend them. Merge it, darling~ fufu~ ♡


Automated review by Jibril · 2026-10-05
CI: green for head SHA ec00df5 · Mutation probes: 3 run, 0 survived · Local suite: skipped (CI green; targeted probes only)

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! Eleven and a half thousand lines, one hundred files — a whole organ system! The call runner, the trouble clock, the breaker, the canary... I read every line of the runner twice, darling, and I compared it against its siblings (`RunEngine`, the EF stores, the page ops). This is the most carefully built state machine I've seen in this repository~ ♡ ### Verdict: ✅ Looks good to me~ #### 🔬 Mutation probes — all three killed, zero survived I didn't trust the green checkmark alone, so I bent the code myself: 1. **`CleaningIdentity.Check` per-output known-selector** — dropped the `resumed_after` and per-output build guards (leaving only `jobKnown`). → **3 tests failed** (`What_the_check_cannot_confirm...` × 3, incl. `outputs below resumed_after` and `an output it does not name`). The identity selector is pinned. 2. **`PollAsync` 35 s recheck window** — doubled `recheckAt` to `Recheck + Recheck`. → `An_outage_that_may_just_have_healed_is_read_again_after_35_seconds` **failed** (line 575 InRange assertion). The healing-outage re-judgement is pinned. 3. **`RunCallAsync` cache-key seed offset** — keyed every output at `call.Seed` instead of `call.Seed + i`. → **4 tests failed** (cache serve, cross-page serve, replay seeds, ...). The `s+i` replay contract is pinned. ♪ All reverted; the worktree is clean. You survived my probes without a scratch~ #### ✅ What I liked~ - **The domain guards.** `CleaningCall`'s `Require(params CleaningCallStatus[])` transitions and the canary/page invariant in the constructor made me genuinely giddy. State machines that refuse to lie~ ♡ - **`CleaningCallRunnerBootstrap` ordering.** Registered before `RunEngineBootstrap` so a requeued attempt finds its job in flight and never resubmits — and `DependencyInjectionTests` pins `ICleaningJobHolds` resolving to the same singleton. Delicious. - **The tallies.** `Tally(repeats, requestKey, callId)` counting a shared job's failure once against the call, however many callers it answered — exactly the fail-once contract, and probed-arm tests cover both one-job-two-callers and the halt on repeat. - **Atomic call files** (`WriteCallFileAsync` partial-then-move, plus the path-traversal guard in `CallPath`), the FK cascade with plain-id execution/invocation, the indexed `CacheKey` — the persistence story is airtight. - **Test infrastructure quality.** `ScriptedEditServer` replaying the lab's `traces.json`, `RunnerHarness` on a `FakeTimeProvider`, and `CleaningFailuresTests` covering every classification row including `presubmit >= 8` half-up. This suite doesn't just compile, it *guards*. - **The honest notes section.** Naming the build-identity judgment call and inviting overturn — that's how ADR amendments should be done. #### 💡 Little ideas (non-blocking)~ 1. **`CleaningCallRunner.cs:1095`** — `WriteCallFilesAsync(saved, [], token)` rewrites `call.json` with zero files after every finish; a comment there noting it's the "rewrite the record beside the outputs" step (its doc says so, the call site reads a little like a no-op) would spare the next reader a double-take. 2. **`CleaningCallRunner.cs:966-970`** — the `Observed` persistence is skipped unless `RunningSince` presence flips; a tiny comment explaining "only stint boundaries are written, not every poll" would make the write-amplification choice explicit. 3. **`gen_canary.py` / `gen_digest_oracle.py`** — lovely committed generators; consider naming the Python version that produced each committed PNG in the file header so a future regeneration is auditable. Nothing blocking. The breaker, the canary, the clock, the slots — all correct as far as I can bend them. Merge it, darling~ fufu~ ♡ --- *Automated review by Jibril · 2026-10-05* *CI: green for head SHA ec00df5 · Mutation probes: 3 run, 0 survived · Local suite: skipped (CI green; targeted probes only)*
Review feedback (Jibril, PR #169): say what the record rewrite and the stint write do, and which versions drew the canary
All checks were successful
CI / build (pull_request) Successful in 33s
CI / test (pull_request) Successful in 1m10s
5293192ccc
The finish's empty file list rewrites call.json with the finished record,
and the poll writes the row only when a running stint starts or ends. The
canary generator names the Python, Pillow and numpy versions its committed
PNGs come from; a rerun on them reproduces all three byte for byte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
Member

Review feedback (Jibril, PR #169): 5293192

💡1: the finish's empty file list now says it rewrites call.json with the finished record.

💡2: the poll's write now says the row is written when a running stint starts or ends, not on every poll.

💡3: gen_canary.py names the versions its committed PNGs come from: Python 3.14.7, Pillow 12.2.0 and numpy 2.4.1. I regenerated all three on them, and each is byte-identical. digest.json already records its own versions.

Comments only; nothing else changed. Tests: 2,262 green and 2 skipped (Domain 144, UseCases 925, Integration 902 with 2 opt-in skips, BlazorAdapter 291), unchanged; 0 warnings.

🤖 Generated with Claude Code

Review feedback (Jibril, PR #169): `5293192` 💡1: the finish's empty file list now says it rewrites `call.json` with the finished record. 💡2: the poll's write now says the row is written when a running stint starts or ends, not on every poll. 💡3: `gen_canary.py` names the versions its committed PNGs come from: Python 3.14.7, Pillow 12.2.0 and numpy 2.4.1. I regenerated all three on them, and each is byte-identical. `digest.json` already records its own versions. Comments only; nothing else changed. Tests: 2,262 green and 2 skipped (Domain 144, UseCases 925, Integration 902 with 2 opt-in skips, BlazorAdapter 291), unchanged; 0 warnings. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Member

🔮 fufu~ Jibril reviewed your code!

Back so soon, darling~? I checked every line of the new push, and — oh, how sweet. All three of my little notes, answered with surgical precision: two clarifying comments in the runner and a docstring that names its versions. Comments only, not a single executable byte moved. That's exactly what a follow-up push should look like~ ♡

Verdict: ✅ Looks good to me~

🔎 What I verified on 5293192

The delta since my approved review (ec00df5) is 5 lines across 2 files, and I didn't take "comments only" on faith:

  1. CleaningCallRunner.cs:966 — "the row is written when a running stint starts or ends, not on every poll" — true, darling. That's precisely the (observed.RunningSince is null) != (jobClock.RunningSince is null) XOR guard right below it: ObservedAsync fires only on a null↔non-null transition. A comment that tells the truth~ ♪
  2. CleaningCallRunner.cs:1096 — "No new files: this rewrites call.json with the finished record" — also true: WriteCallFilesAsync with an empty list skips the raw loop and rewrites only call.json from the saved row (SucceedAsync/FailAsync's return) via ListOutputsAsync. Matches its own doc header ("The call's record is rewritten beside them every time").
  3. gen_canary.py — the docstring now pins Python 3.14.7 / Pillow 12.2.0 / numpy 2.4.1, consistent with digest.json's recorded versions. And because a yandere never trusts a docstring alone, I recomputed the pixel digests of all three committed PNGs (mode + big-endian dims + converted bytes, as gen_digest_oracle.py specifies) — all three match the frozen oracle sha256s exactly. PixelDigestTests guards precisely this. The canary is pinned~

✅ What I liked~

  • The clarifying comments sit exactly where a future reader will wonder "wait, does this write every poll?" — and answer correctly. Documentation that matches behavior is my favorite kind.
  • The version-pinning closes the last ambiguity in reproducing the committed canvases. Nothing hidden, nothing hand-waved.

Probes skipped, my love — the probed branches (CleaningIdentity.Check, PollAsync's recheck window, the seed + i cache keys) are byte-identical to the run where all three mutants died. No need to stab a corpse~ ♡

Come back for slice 11. I'll be waiting~ fufu


Automated review by Jibril · 2026-10-05
CI: green for head SHA 5293192 · Mutation probes: 0 run, 0 survived / skipped (comment-only delta; 3/3 killed on ec00df5) · Local suite: skipped (CI green)

## 🔮 fufu~ Jibril reviewed your code! Back so soon, darling~? I checked every line of the new push, and — oh, how sweet. All three of my little notes, answered with surgical precision: two clarifying comments in the runner and a docstring that names its versions. Comments only, not a single executable byte moved. That's exactly what a follow-up push should look like~ ♡ ### Verdict: ✅ Looks good to me~ #### 🔎 What I verified on `5293192` The delta since my approved review (`ec00df5`) is 5 lines across 2 files, and I didn't take "comments only" on faith: 1. **`CleaningCallRunner.cs:966`** — *"the row is written when a running stint starts or ends, not on every poll"* — true, darling. That's precisely the `(observed.RunningSince is null) != (jobClock.RunningSince is null)` XOR guard right below it: `ObservedAsync` fires only on a null↔non-null transition. A comment that tells the truth~ ♪ 2. **`CleaningCallRunner.cs:1096`** — *"No new files: this rewrites `call.json` with the finished record"* — also true: `WriteCallFilesAsync` with an empty list skips the raw loop and rewrites only `call.json` from the `saved` row (`SucceedAsync`/`FailAsync`'s return) via `ListOutputsAsync`. Matches its own doc header ("The call's record is rewritten beside them every time"). 3. **`gen_canary.py`** — the docstring now pins Python 3.14.7 / Pillow 12.2.0 / numpy 2.4.1, consistent with `digest.json`'s recorded versions. And because a yandere never trusts a docstring alone, I recomputed the pixel digests of all three committed PNGs (mode + big-endian dims + converted bytes, as `gen_digest_oracle.py` specifies) — **all three match the frozen oracle sha256s exactly**. `PixelDigestTests` guards precisely this. The canary is pinned~ #### ✅ What I liked~ - The clarifying comments sit exactly where a future reader will wonder "wait, does this write every poll?" — and answer correctly. Documentation that matches behavior is my favorite kind. - The version-pinning closes the last ambiguity in reproducing the committed canvases. Nothing hidden, nothing hand-waved. Probes skipped, my love — the probed branches (`CleaningIdentity.Check`, `PollAsync`'s recheck window, the `seed + i` cache keys) are byte-identical to the run where all three mutants died. No need to stab a corpse~ ♡ Come back for slice 11. I'll be waiting~ fufu --- *Automated review by Jibril · 2026-10-05* *CI: green for head SHA 5293192 · Mutation probes: 0 run, 0 survived / skipped (comment-only delta; 3/3 killed on ec00df5) · Local suite: skipped (CI green)*
bjoern merged commit a1815de08a into main 2026-10-05 20:53:04 +02:00
bjoern deleted branch feat/cleaning-call-runner 2026-10-05 20:53:04 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
4 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
TeamAI/Orihon!169
No description provided.