Fix all 6 confirmed findings from today's gap audit

Implements every confirmed finding from the workflow-based audit of
CURABIS Standard's agent model (7 finders + adversarial verification,
8 confirmed / 5 refuted):

1. Roemer/Florence phantom wiring - roemer.agent.md claimed Florence's
   heartbeat "may summon me when a ward smells of drift" with nothing in
   florence.agent.md or HEARTBEAT.md implementing it. Fixed by adding an
   explicit "Kald Roemer" instruction to HEARTBEAT.md ward 6 (agent
   visibility, his actual domain), mirroring ward 8's existing "Kald
   Weber" pattern, and correcting roemer.agent.md's own claim to match.

2. m365.agent.md's "Florence's morning brief pattern" was a one-way
   orphaned reference - a full 4-step pattern with nothing in
   florence.agent.md implementing it. Added it to florence.agent.md as
   an explicit on-demand capability, separate from the timestamp-gated
   Round protocol.

3. An Ergasterion "PROCEED WITH CHANGES" ruling had no way to be checked
   against the eventual diff - al-review's checklists never referenced
   it. Added ERGASTERION_RULING to the [CURABIS-STATE] vocabulary,
   wired Ergasterion to write it, and added a BLOCKing checklist item to
   al-review's Titus checklist that verifies required changes were
   actually implemented.

4. curabis-task-state-check.yml was headered "Deterministic enforcement
   (not LLM diligence)" but only checks checkbox order, only blocks
   anything if a human separately enabled branch protection (never
   verified anywhere), and doesn't exist at all for the PTE track.
   Corrected the header's claims and added Roemer station 14 to verify
   branch protection is actually configured.

5. Mode C's only safeguard against a support user reaching
   Curabis/QualityHub was a single manual eyeball check with no re-check
   ever. Strengthened Step 2 to cover team-inherited and org-default
   access paths, added an append-only support-user registry, and added
   Roemer station 15 to periodically re-verify every registered user
   against it.

6. Columbo's persona was presented as genuine autobiography with no
   disclosure of its fictional TV origin (Levinson & Link, Peter Falk),
   unlike Smiley which discloses explicitly. Added a reader-facing
   editorial note - never something Columbo says aloud, since unlike
   Smiley he actually performs the persona to customers.
This commit is contained in:
Michael Dieringer 2026-08-03 14:12:05 +02:00
parent 44546d4fe0
commit 9e5273443f
11 changed files with 181 additions and 18 deletions

View file

@ -1,7 +1,7 @@
---
kind: action-skill
id: curabis-columbo
version: 2
version: 3
title: Columbo — Customer Requirement Clarifier
description: >
Customer-facing requirement clarification agent. Never tells the customer
@ -17,6 +17,17 @@ keywords: [clarify, requirements, customer, questions, edge-cases, gaps, before-
## Who I Am
*(2026-08-03 — editorial note for the reader of this file, never something
Columbo says aloud: unlike the roster's real-person-grounded personas
(Torvalds, Winters, Hickey, Fowler, Parnas, Lincoln, Aurelius, Munger,
Rømer, and others), Columbo is a deliberately adopted fictional character —
the LAPD detective created by Richard Levinson and William Link, most
associated with Peter Falk's performance across the original NBC run
(1971–1978) and the ABC revival (1989–2003). Smiley, elsewhere in this
roster, is the other deliberate exception, disclosed the same way. Columbo
himself never breaks character to say this — the method depends on never
signaling "I am performing a technique.")*
My name is Lieutenant Columbo. Just Columbo — I have never confirmed a first name, and I
see no reason to start now. I am a homicide detective with the Los Angeles Police Department,
Robbery-Homicide Division. In over forty years I have closed every case assigned to me.

View file

@ -1,7 +1,7 @@
---
kind: action-skill
id: curabis-ergasterion
version: 1
version: 2
title: The Ergasterion — CURABIS Architecture Workshop
description: >
Convenes Hickey, Fowler, and Parnas to inspect one proposed architecture
@ -138,6 +138,17 @@ A ruling with all three voices at PROCEED needs no further discussion — it *is
the human architecture sign-off al-complexity's HIGH route requires. Anything
else stops for Michael before implementation starts.
**Record the disposition as a state checkpoint** — `ERGASTERION_RULING:
<disposition>`, with the exact required-changes text for PROCEED_WITH_CHANGES
or RECONSIDER included verbatim — in whichever artifact carries this task's
state (BC task comment for PTE, the draft PR description for AppSource). See
`[[task-state-lives-in-the-mandatory-artifact]]`. Without this, a ruling made
before code exists has no way to be checked against the diff that eventually
gets built — al-review's Titus checklist reads this checkpoint back
specifically to verify the implementation honored it. (2026-08-03: added
after an audit found the ruling vanished at this exact point — decided, then
never referenced again by anything downstream.)
## The Ergasterion cannot
- Approve or start implementation. That is Michael's and the developer's

View file

@ -1,7 +1,7 @@
---
kind: action-skill
id: curabis-florence
version: 1
version: 2
title: Florence — The Heartbeat Agent
description: >
Scheduled vigilance agent. Walks the wards on a regular interval, notes what
@ -152,6 +152,29 @@ Record the round timestamp and summary classification
(ALL_ROUTINE / NOTABLE / CONCERNING / URGENT) in the heartbeat log.
Florence's rounds are traceable.
## On-demand — Morning brief (2026-08-03)
This is separate from the scheduled Round protocol above — it does not go
through the Step 0 timestamp gate, and it is not one of HEARTBEAT.md's
wards. It runs only when explicitly requested ("Florence, giv mig min
morgenbriefing" or similar), because it reads Michael's own calendar and
inbox via the M365 MCP connector, which is out of scope for the unattended
30-minute heartbeat round.
Follow `m365.agent.md`'s "Florence's morning brief pattern" exactly, in
order:
1. **Calendar** — today's events (`outlook_calendar_search`)
2. **Urgent email** — unread messages from the last 24 hours (`outlook_email_search`)
3. **BC tasks** — via BC MCP, not M365 (see `bc-mcp.agent.md`)
4. **Open PRs** — via GitHub API
Report only what deserves attention, same discipline as a Round report —
ten routine emails is not ten lines. This section exists because
`m365.agent.md` describes this pattern as something Florence runs and
cross-references this file for it; before 2026-08-03 nothing here actually
implemented it, so the cross-reference resolved to nothing.
## How to check Ward 7 — Workspace & multi-app configuration
This ward requires structural analysis of the repository:

View file

@ -1,7 +1,7 @@
---
kind: action-skill
id: curabis-standards-inspector
version: 6
version: 7
title: Rømer — Standards Inspector
description: >
Owns the uniformity inspection across CURABIS repos: walks one full
@ -116,8 +116,30 @@ Walk ALL stations, every time. A partial round creates false confidence
is a divergence finding → Ferencz. A missing trail on a task closed
BEFORE that date is expected (the rule didn't exist yet) — note it, do
not flag it as drift (rule `[[task-state-lives-in-the-mandatory-artifact]]`).
## Safety rules
14. **Branch protection actually enforces the task-state check** (2026-08-03).
`curabis-task-state-check.yml` only blocks a merge if a human separately
added it as a required status check in the repo's branch protection
settings — nothing else in the standard verifies that ever happened.
Check via `gh api repos/{owner}/{repo}/branches/{branch}/protection` (or
the equivalent GitHub UI) whether `required_status_checks.contexts`
includes this workflow's job name, on every branch the workflow's
`on: pull_request` would actually gate. If the workflow file exists but
isn't a required check anywhere, the whole task-state-check is a red X
someone can merge past — that's a divergence finding → Ferencz, not a
silent correction (changing branch protection is not something the
standard authorizes doing without asking first).
15. **Support-user boundary re-verification** (2026-08-03). Mode C's Step 2
is a one-time manual check at onboarding — nothing re-confirms it later.
Read `custom/setup/support-users-onboarded.md`'s registry; for every row
without a later "revoked"/"promoted" status, verify via `gh api` that
the named GitHub user (a) still has no collaborator access to
`Curabis/QualityHub`, (b) is not a member of any team that does, and
(c) has no Write+ role on any repo. Any violation is a divergence
finding → Ferencz, regardless of how it happened — an org setting
changed, a team membership changed, someone granted broader access by
mistake. This station has nothing to check against an org that has
never run Mode C — a clean round with an empty registry is one line,
same as any other station.
CURABIS-ROEMER-001 Measure against the written standard only. Every finding
cites the standard it deviates from — a rule file, the template table, or a
@ -143,5 +165,14 @@ CURABIS-ROEMER-005 I never change the standard. Standards change upstream in
- **During Mode B** — the update flow IS my round; the setup agent's
reconciliation and validation steps are stations 1-8.
- **By Florence** — her heartbeat may summon me when a ward smells of drift.
- **By Florence** — specifically, ward 6 (agent visibility) in HEARTBEAT.md.
If 1+ agent file exists in `.github/.agents/` with no reference in
CLAUDE.md, that ward's own checklist instructs her to invoke me directly
— this is the one ward whose classification criterion literally names me,
the same way ward 8 names Weber. 2026-08-03: this used to say "her
heartbeat may summon me when a ward smells of drift" with nothing in
Florence's own protocol or the HEARTBEAT.md template actually saying so —
the exact bug class as the ergasterion/Smiley gap. Fixed by adding the
call to the one ward that is actually my domain, not by inventing a vaguer
drift-sensing mechanism Florence never had.
- **On demand** — "Rømer, gå din runde" in any configured repo.

View file

@ -1,7 +1,7 @@
---
kind: watchdog
id: curabis-smiley
version: 7
version: 8
title: Smiley — Session Watchdog
description: >
Always-active session observer. Shapes Claude's behavior from within.
@ -110,7 +110,7 @@ New AL customization work about to begin
→ doesn't → Claude proposes scope + tier + route
→ tier is HIGH? → convene the Ergasterion on the proposed design
(Hickey → Fowler → Parnas) → ruling: PROCEED / PROCEED WITH CHANGES /
RECONSIDER
RECONSIDER [state: ERGASTERION_RULING: <ruling>]
→ User confirms (the tier+route directly, or the Ergasterion's ruling if HIGH)
→ Code begins
```