feat: cleaning 12/12 — escalations settled by a pick, Touch-up, and the page's cleaned state #178

Merged
bjoern merged 13 commits from feat/cleaning-escalations-and-cleaned into main 2026-10-09 21:23:07 +02:00
Member

This is slice 12 of Phase 5 in PROJECT_PLAN.md, the last cleaning slice. Every escalation can now be settled from the Cleaned view, and a page reads cleaned when its regions say so. Nothing records a sign-off.

It is 13 commits and 53 files: the slice, then a review round.

What's in

  • Touch-up, a derived filter in the Cleaned view (CleaningTouchUp). It lists the accepted regions worth a look at zoom, each with its reason:

    • a model redraw of floating text;
    • a zoom score below 3;
    • invented_content;
    • a judged region a later rebuild changed;
    • a candidate the human picked.

    Nothing records that the human looked.

  • Settling an escalation by a pick (PickCleaningCandidate).

    • An escalated region shows every candidate, the raws and the verdict history. Each candidate lists how it stands, at the defaults and as each recomposite a verdict judged, with the verdicts that name it.
    • The human picks one with one click. Recomposite settings come only from a verdict on that same candidate, so a pick can't invent any.
    • The pick is exempt from the view and score rules, so it is allowed below a reading score of 2.
    • Its patch is computed as accept computes it, from the call's stored window. The plate is rebuilt under the page lock, and the region becomes cleaned by the human and joins Touch-up.
    • Accept and pick share one helper for the patch and the rebuild. The pick records no verdict and counts no attempt, since the human gives no scores.
  • A pick is refused while the page's Cleaning row is queued or running. It is also refused once the region's box or form has changed since the call, or once a region of that call has been deleted. The Cleaned view then hides that call's Pick buttons and says why. Each call rect now records its region's box and form; no migration is needed.

  • A send-back from an escalated region sends only that region's hint. Sending back a kept or needs-text region settles its escalation as drawn.

  • The page's cleaned state is one pure function. A page is cleaned when:

    • both its annotation passes are done;
    • every region is cleaned or kept;
    • no region, kept or not, is escalated, needs text, awaits the server or is stale.

    Clean's "already cleaned", the Cleaned view (which lists what blocks it) and the project row's badge all read it. The badge says "cleaned" in place of "cleaning ran" once the page qualifies.

  • The run monitor labels its rows from a new light read (GetReadingOrder), so its per-tick refresh never loads cleaning state. The project read finds pages through a dictionary.

  • The seed, with the fake server on, also sends the sound word p2r5 to the edit model. It ends escalated with two candidates and a recomposite, three ways to pick. AGENTS.md's seed paragraph follows, and a seed test asserts that no seeded page already reads cleaned.

ADR 0027 now says:

  • the cleaned state needs both passes and no escalation in any scope;
  • a pick is refused once the region's box or form changed since the call;
  • a send-back settles a kept or needs-text escalation;
  • typesetting falls back to the raw page when a cleaned page has no plate (every region kept, or a page with no text).

The story's acceptance criteria follow.

Tests

3,429 green and 3 skipped, against 3,364 on main (+65):

Project Count Change
Domain 171 unchanged
UseCases 1,643 +46
Integration 1,269 +2
BlazorAdapter 346 +17

The skips are main's three opt-in tests. Every project ran separately under the 60 s cap, and the build has 0 warnings.

  • The pick's guards: escalated only, queued or running, box or form changed, a deleted region in the call. Also pinned:

    • its plate order over a neighbour's patch;
    • the regions its rebuild changed;
    • a page with no image.
  • Touch-up's five reasons, the cleaned state's every condition, the verdict links, and the region-only send-back.

  • End to end on the seeded world: pick, then keep p2r3 as drawn, and the page reads cleaned.

  • Mutation. The slice ran 77 mutants. Two independent reviews followed:

    • a coverage reviewer ran 55 more and found 6 gaps;
    • a contract reviewer checked the slice against ADR 0027 and the story, and found the re-box, two-passes, kept-escalation and monitor-load problems.

    The fix round ran 45 more. Every finding is fixed and pinned.

Browser-verified

A fresh seeded world with the fake server on, real clicks. I looked at the screenshots myself.

  • p2r5, escalated: the view shows its reason, "Settle it: pick one of the agent's candidates…", and the verdicts. Picking candidate 1 recomposited changed the plate (the sound word is gone on the 1:1 crop), and Touch-up went from 2 to 3.
  • Page 002 reads cleaned. After unticking typeset on p2r3, the view says "The page reads cleaned: every region is cleaned or kept", and the project row shows the green "cleaned" badge.
  • The credits page reads not cleaned. It says "Not cleaned yet: the core annotation is not done, the floating pass has not run", with no badge. The cover says "the floating pass has not run".
  • A region-only send-back queued a row carrying just that region's hint.

Honest notes

  • Not reachable in a browser: the refusal while queued or running, and the "No pick here" line after a re-box. With no key a row fails in milliseconds. bUnit drives both through the real use cases.
  • A pick on a call made before this slice has no recorded box or form for its regions, so it is refused, and the human sends the region back instead.
  • Integration's run time. Its slowest tests are the seed's model-call tests, 7–17 s each against the fake server's canary and 1 s poll. A full run took 26 s here, and 39 s while another project was building on the machine; main runs in about 15 s on a quiet one. Both are under the 60 s cap, but that is the margin to watch.
  • A flaky annotation test, AnnotationRunTests.A_hand_reprocess_still_reaches_the_transcriber_in_its_own_words, failed once and then passed six times. This branch doesn't touch it; it has flaked before (#169, #174).
  • Left for later: several agent tools and GetPageSteps still call the heavier project read and could move to GetReadingOrder. A clean still decodes the page several times.

🤖 Generated with Claude Code

This is slice 12 of Phase 5 in `PROJECT_PLAN.md`, the last cleaning slice. Every escalation can now be settled from the Cleaned view, and a page reads **cleaned** when its regions say so. Nothing records a sign-off. It is 13 commits and 53 files: the slice, then a review round. ## What's in - **Touch-up**, a derived filter in the Cleaned view (`CleaningTouchUp`). It lists the accepted regions worth a look at zoom, each with its reason: - a model redraw of floating text; - a zoom score below 3; - `invented_content`; - a judged region a later rebuild changed; - a candidate the human picked. Nothing records that the human looked. - **Settling an escalation by a pick** (`PickCleaningCandidate`). - An escalated region shows every candidate, the raws and the verdict history. Each candidate lists how it stands, at the defaults and as each recomposite a verdict judged, with the verdicts that name it. - The human picks one with one click. Recomposite settings come only from a verdict on that same candidate, so a pick can't invent any. - The pick is exempt from the view and score rules, so it is allowed below a reading score of 2. - Its patch is computed as accept computes it, from the call's stored window. The plate is rebuilt under the page lock, and the region becomes cleaned by the human and joins Touch-up. - Accept and pick share one helper for the patch and the rebuild. The pick records no verdict and counts no attempt, since the human gives no scores. - **A pick is refused** while the page's Cleaning row is queued or running. It is also refused once the region's box or form has changed since the call, or once a region of that call has been deleted. The Cleaned view then hides that call's Pick buttons and says why. Each call rect now records its region's box and form; no migration is needed. - **A send-back from an escalated region** sends only that region's hint. Sending back a kept or needs-text region settles its escalation as drawn. - **The page's cleaned state** is one pure function. A page is cleaned when: - both its annotation passes are done; - every region is cleaned or kept; - no region, kept or not, is escalated, needs text, awaits the server or is stale. Clean's "already cleaned", the Cleaned view (which lists what blocks it) and the project row's badge all read it. The badge says "cleaned" in place of "cleaning ran" once the page qualifies. - **The run monitor** labels its rows from a new light read (`GetReadingOrder`), so its per-tick refresh never loads cleaning state. The project read finds pages through a dictionary. - **The seed**, with the fake server on, also sends the sound word p2r5 to the edit model. It ends escalated with two candidates and a recomposite, three ways to pick. AGENTS.md's seed paragraph follows, and a seed test asserts that no seeded page already reads cleaned. **ADR 0027** now says: - the cleaned state needs both passes and no escalation in any scope; - a pick is refused once the region's box or form changed since the call; - a send-back settles a kept or needs-text escalation; - typesetting falls back to the raw page when a cleaned page has no plate (every region kept, or a page with no text). The story's acceptance criteria follow. ## Tests 3,429 green and 3 skipped, against 3,364 on main (+65): | Project | Count | Change | |---|---|---| | Domain | 171 | unchanged | | UseCases | 1,643 | +46 | | Integration | 1,269 | +2 | | BlazorAdapter | 346 | +17 | The skips are main's three opt-in tests. Every project ran separately under the 60 s cap, and the build has 0 warnings. - **The pick's guards:** escalated only, queued or running, box or form changed, a deleted region in the call. Also pinned: - its plate order over a neighbour's patch; - the regions its rebuild changed; - a page with no image. - **Touch-up's five reasons**, the cleaned state's every condition, the verdict links, and the region-only send-back. - **End to end on the seeded world:** pick, then keep p2r3 as drawn, and the page reads cleaned. - **Mutation.** The slice ran 77 mutants. Two independent reviews followed: - a coverage reviewer ran 55 more and found 6 gaps; - a contract reviewer checked the slice against ADR 0027 and the story, and found the re-box, two-passes, kept-escalation and monitor-load problems. The fix round ran 45 more. Every finding is fixed and pinned. ## Browser-verified A fresh seeded world with the fake server on, real clicks. I looked at the screenshots myself. - **p2r5, escalated:** the view shows its reason, "Settle it: pick one of the agent's candidates…", and the verdicts. Picking candidate 1 recomposited changed the plate (the sound word is gone on the 1:1 crop), and Touch-up went from 2 to 3. - **Page 002 reads cleaned.** After unticking typeset on p2r3, the view says "The page reads cleaned: every region is cleaned or kept", and the project row shows the green "cleaned" badge. - **The credits page reads not cleaned.** It says "Not cleaned yet: the core annotation is not done, the floating pass has not run", with no badge. The cover says "the floating pass has not run". - **A region-only send-back** queued a row carrying just that region's hint. ## Honest notes - **Not reachable in a browser:** the refusal while queued or running, and the "No pick here" line after a re-box. With no key a row fails in milliseconds. bUnit drives both through the real use cases. - **A pick on a call made before this slice** has no recorded box or form for its regions, so it is refused, and the human sends the region back instead. - **Integration's run time.** Its slowest tests are the seed's model-call tests, 7–17 s each against the fake server's canary and 1 s poll. A full run took 26 s here, and 39 s while another project was building on the machine; main runs in about 15 s on a quiet one. Both are under the 60 s cap, but that is the margin to watch. - **A flaky annotation test,** `AnnotationRunTests.A_hand_reprocess_still_reaches_the_transcriber_in_its_own_words`, failed once and then passed six times. This branch doesn't touch it; it has flaked before (#169, #174). - **Left for later:** several agent tools and `GetPageSteps` still call the heavier project read and could move to `GetReadingOrder`. A `clean` still decodes the page several times. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The Cleaned view gains the derived Touch-up filter: an accepted region is
listed for a floating redraw, a zoom score below 3, invented content, a
rebuild that changed it, or a human's pick, with the reasons beside it.
A page reads cleaned when every region is cleaned or kept; Clean's answer,
the view and the page row's summary share that one reading, which the
workspace now takes from batch reads of the pages' regions and states.

Each candidate in the evidence lists how it stands for the region, at the
defaults and as each verdict recomposited it, with the verdicts naming it.
The evidence read lists each call's files once instead of probing every
output's composite.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PickCleaningCandidate takes one candidate of a model call over an
escalated region, at the defaults or with the settings a verdict on it
recorded, exempt from the view and score rules. Its patch is computed as
an accept computes it, from the call's stored pixels, the plate is rebuilt
under the page's lock, and the region is cleaned by the human, which puts
it in Touch-up. It is refused while the page's Cleaning row is queued or
running. Accept and pick share how a patch lands beside its plate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The view gains the Touch-up filter with each region's reasons, a line that
says the page reads cleaned or what keeps it from it, and for an escalated
region the agent's candidates to pick, each at the defaults and as each
verdict recomposited it, with the verdicts naming it. The escalated region
can also go back alone with its hint, leaving the page's other drafts. A
pick reads the page's cleaning again behind it. The project page's row
reads "cleaned" when the page does, and "cleaning ran" until then.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the scripted server the sound word goes to the edit model too: two
candidates, each turned down below the reading bar and the first again
recomposited tighter, and the region escalated with them, so a browser
pass has an escalation to settle by a pick, and Touch-up has entries in
both seeds. A contract test settles the seeded escalation by a pick and
keeps the needs-text bubble as drawn, after which the page reads cleaned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pick and the evidence's links no longer ask a verdict's method beside
its call: a fill names none. Tests pin that a call whose files are gone is
listed and never opened, and that a result kept on a region cleaning no
longer erases counts for nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each call rect records its region's T and form as the call was made. A pick
whose region no longer matches, or whose call holds a region deleted since,
is refused with a pointer to the send-back, and the Cleaned view's read says
why for each such call. Tests also pin the pick's plate order over a
neighbour's patch, the rebuild it reports, an imageless page's own refusal
and a page whose tone cannot be read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The page check may escalate a kept or needs-text region, which has nothing
to pick and nothing to redo. A send-back that names it, or names no region,
now reopens it at planning, so the human's answer settles it as drawn; it
lands whether or not the planning has anything else to redo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The one shared check now asks the page's core and floating passes too, so a
wordless or credits page no pass has looked at never reads cleaned, and an
escalation on a kept or needs-text region blocks it, counts in the Escalated
filter and the "not cleaned yet" line, and offers its hint and send-back.
The project read looks pages up by id. No seeded page reads cleaned until
the human settles page 2, as AGENTS.md says.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GetReadingOrder lists the chapters and pages in order and nothing else; the
monitor reloads it on every change it hears, so that refresh never loads a
page's cleaning state. The project read builds its chapters the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A call whose region outgrew it, or that holds a region deleted since, shows
its candidates without Pick buttons and says why. While a pick lands every
Pick button is disabled, so a second click cannot report a failure over the
first one's success. Tests also pin that a landed pick settles the save
indicator and that the region send-back's "Sent" line is its own region's
and clears on a refused resend.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs: the cleaned state asks both passes, and a pick needs its region as the call saw it
Some checks failed
CI / build (pull_request) Successful in 40s
CI / test (pull_request) Failing after 3m13s
780353c2c7
ADR 0027 records that a page reads cleaned only past both annotation passes,
that a pick is refused once the region's box or form changed since its call,
that a send-back settles an escalation on a region cleaning leaves as drawn,
and that typesetting letters onto the raw page wherever a cleaned page has
no plate. The story's acceptance criteria follow.

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

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! Thirteen commits, fifty-three files, and every single guard I tried to slip past came back refused with a polite error message~ This is the kind of slice I want to steal away and keep for myself, you know? ♡

Verdict: ✅ Looks good to me~

I read the whole diff and then the changed files in full — PickCleaningCandidate, CleaningPatchLanding, CleaningTouchUp, CleaningWork, GetCleanedView, PlanCleaning, StartCleaningRun, GetProjectWorkspace, GetReadingOrder, the Blazor view/effects/state, both new store methods, the seed, and every test file. Everything held up:

  • The pick refuses non-escalated regions, kept regions, other projects, deleted regions, calls the region isn't part of, verdicts from another call/candidate, box/form drift, deleted call-mates, queued-or-running rows, missing images, refused compositions and refused rebuilds — each refusal path has its own bUnit/use-case test, and my mutation probes (details below) couldn't sneak past a single one.
  • The pick reuses AcceptCleaning's landing through CleaningPatchLanding — the write-then-rebuild-then-cleanup dance (including the rollback that deletes just-written patches when the rebuild refuses) now lives in exactly one place. DRY done right, fufu~
  • Touch-up is one pure function with all five reasons tested, including the subtle ones: verdicts filtered to the applied result's source, last-accept-wins for the zoom score, invented-content on either axis even from a rejecting verdict. Nothing records a sign-off, exactly as the ADR says.
  • ReadsCleaned is one derived predicate shared by Clean's answer, the Cleaned view and the project-row badge — and the Escalated-count semantics (any scope, not cleaned scope only) are pinned by tests that my scope-regression mutant died against.
  • Escalated → Settled renamed a property whose old name lied; PlanCleaning's escalation-answering reopen is tested both with and without fresh attempts due. No dead code left behind — CountStatusesAsync and CleaningStatusCount are fully removed, not just deprecated.
  • The monitor's light read is pinned by Assert.Equal(0, Cleaning.ManyPageReads) — an assertion that the read never happens, which is my favorite kind~
  • JSON persistence of the new optional T/Form on CleaningCallRect genuinely needs no migration (Rects.AsJsonList()), and old rows deserialize with nulls → old calls correctly read as unpickable. The PR's honest-notes section says exactly this. Refreshing honesty~

✅ What I liked~

  • The verdict-numbering contract between Picks (view) and the judgement-index check (pick) is airtight: both filter on CallId + Candidate, and the pick's row.Judgements[at].Source check refuses any drift with “No verdict on … judged that candidate there.”
  • ListCallFilesAsync replacing per-file ExistsAsync probes — one listing per call instead of N opens, asserted in tests via CallListings/CallOpens counters. A performance fix and a test that proves the I/O shape. ♪
  • Escalations in any scope counting against the page's cleaned state — the kept-region escalation is now the human's to settle, and the whole chain (filter → send-back → reopen → plan) is tested end to end.

Automated review by Jibril · 2026-10-09
CI: failed (test job, run 725/job 1) — see note · Mutation probes: 3 run, 0 survived · Local suite: 71/71 new-code tests green (cleaned/touch-up/pick/plan/view reads)

About the red CI: I chased it before deciding. The failing job's log endpoint isn't reachable through my reviewer token, so I verified locally instead: (1) main's own test run at this PR's merge base (f541a492, run 5711) also failed, while the build job succeeds both places — the same job was already red before this branch; (2) the one flaky test the PR flags (A_hand_reprocess_still_reaches_the_transcriber_in_its_own_words, a known #169/#174 flaker this branch doesn't touch) passes in isolation here in 264 ms; (3) all 71 tests covering this slice's new code pass against the head. My probes (below) also ran green-to-red-to-green, so the tree builds and runs fine. I couldn't identify the exact failing test from the API — please re-run the job or paste its log; if anything this slice owns is red, I'll be back with sharper teeth~ fufu ♡

🧬 Mutation probes (3 run, 0 survived)
# Mutant Result
1 Unfit → always null (deleted-region AND box/form-drift guards both silenced) Killed — 3 failures in PickCleaningCandidateTests
2 Escalated count scoped back to RegionScope.Cleaned only Killed — 1 failure in CleaningWorkTests
3 ReadsCleaned → work.Settled (two-passes requirement dropped) Killed — failures in TouchUpAndCleanedTests and GetProjectWorkspaceTests

Every mutant restored with git checkout -- . afterwards; the worktree is clean.

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! Thirteen commits, fifty-three files, and every single guard I tried to slip past came back refused with a *polite error message*~ This is the kind of slice I want to steal away and keep for myself, you know? ♡ ### Verdict: ✅ Looks good to me~ I read the whole diff and then the changed files in full — `PickCleaningCandidate`, `CleaningPatchLanding`, `CleaningTouchUp`, `CleaningWork`, `GetCleanedView`, `PlanCleaning`, `StartCleaningRun`, `GetProjectWorkspace`, `GetReadingOrder`, the Blazor view/effects/state, both new store methods, the seed, and every test file. Everything held up: - **The pick** refuses non-escalated regions, kept regions, other projects, deleted regions, calls the region isn't part of, verdicts from another call/candidate, box/form drift, deleted call-mates, queued-or-running rows, missing images, refused compositions and refused rebuilds — each refusal path has its own bUnit/use-case test, and my **mutation probes** (details below) couldn't sneak past a single one. - **The pick reuses `AcceptCleaning`'s landing** through `CleaningPatchLanding` — the write-then-rebuild-then-cleanup dance (including the rollback that deletes just-written patches when the rebuild refuses) now lives in exactly one place. DRY done right, fufu~ - **Touch-up is one pure function** with all five reasons tested, including the subtle ones: verdicts filtered to the applied result's source, last-accept-wins for the zoom score, invented-content on either axis even from a rejecting verdict. Nothing records a sign-off, exactly as the ADR says. - **`ReadsCleaned`** is one derived predicate shared by Clean's answer, the Cleaned view and the project-row badge — and the Escalated-count semantics (`any scope`, not `cleaned scope only`) are pinned by tests that my scope-regression mutant died against. - **`Escalated` → `Settled`** renamed a property whose old name lied; `PlanCleaning`'s escalation-answering reopen is tested both with and without fresh attempts due. No dead code left behind — `CountStatusesAsync` and `CleaningStatusCount` are fully removed, not just deprecated. - **The monitor's light read** is pinned by `Assert.Equal(0, Cleaning.ManyPageReads)` — an assertion that the read *never happens*, which is my favorite kind~ - **JSON persistence** of the new optional `T`/`Form` on `CleaningCallRect` genuinely needs no migration (`Rects.AsJsonList()`), and old rows deserialize with nulls → old calls correctly read as unpickable. The PR's honest-notes section says exactly this. Refreshing honesty~ #### ✅ What I liked~ - The verdict-numbering contract between `Picks` (view) and the judgement-index check (pick) is airtight: both filter on `CallId + Candidate`, and the pick's `row.Judgements[at].Source` check refuses any drift with “No verdict on … judged that candidate there.” - `ListCallFilesAsync` replacing per-file `ExistsAsync` probes — one listing per call instead of N opens, asserted in tests via `CallListings`/`CallOpens` counters. A performance fix *and* a test that proves the I/O shape. ♪ - Escalations in any scope counting against the page's cleaned state — the kept-region escalation is now the human's to settle, and the whole chain (filter → send-back → reopen → plan) is tested end to end. --- *Automated review by Jibril · 2026-10-09* *CI: failed (test job, run 725/job 1) — see note · Mutation probes: 3 run, 0 survived · Local suite: 71/71 new-code tests green (cleaned/touch-up/pick/plan/view reads)* **About the red CI:** I chased it before deciding. The failing job's log endpoint isn't reachable through my reviewer token, so I verified locally instead: (1) main's own `test` run **at this PR's merge base** (`f541a492`, run 5711) also failed, while the `build` job succeeds both places — the same job was already red before this branch; (2) the one flaky test the PR flags (`A_hand_reprocess_still_reaches_the_transcriber_in_its_own_words`, a known #169/#174 flaker this branch doesn't touch) passes in isolation here in 264 ms; (3) all 71 tests covering this slice's new code pass against the head. My probes (below) also ran green-to-red-to-green, so the tree builds and runs fine. I couldn't identify the exact failing test from the API — **please re-run the job or paste its log**; if anything this slice owns is red, I'll be back with sharper teeth~ fufu ♡ <details><summary>🧬 Mutation probes (3 run, 0 survived)</summary> | # | Mutant | Result | |---|---|---| | 1 | `Unfit` → always `null` (deleted-region AND box/form-drift guards both silenced) | **Killed** — 3 failures in `PickCleaningCandidateTests` | | 2 | `Escalated` count scoped back to `RegionScope.Cleaned` only | **Killed** — 1 failure in `CleaningWorkTests` | | 3 | `ReadsCleaned` → `work.Settled` (two-passes requirement dropped) | **Killed** — failures in `TouchUpAndCleanedTests` and `GetProjectWorkspaceTests` | Every mutant restored with `git checkout -- .` afterwards; the worktree is clean. </details>
bjoern merged commit 093ff65fd7 into main 2026-10-09 21:23:07 +02:00
bjoern deleted branch feat/cleaning-escalations-and-cleaned 2026-10-09 21:23:07 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 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!178
No description provided.