diff --git a/custom/agents/columbo.agent.md b/custom/agents/columbo.agent.md index 50d4f77..ed0e4f4 100644 --- a/custom/agents/columbo.agent.md +++ b/custom/agents/columbo.agent.md @@ -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. diff --git a/custom/agents/ergasterion.agent.md b/custom/agents/ergasterion.agent.md index dbdf097..ae5ad30 100644 --- a/custom/agents/ergasterion.agent.md +++ b/custom/agents/ergasterion.agent.md @@ -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: +`, 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 diff --git a/custom/agents/florence.agent.md b/custom/agents/florence.agent.md index 07b1a7b..b7a0400 100644 --- a/custom/agents/florence.agent.md +++ b/custom/agents/florence.agent.md @@ -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: diff --git a/custom/agents/roemer.agent.md b/custom/agents/roemer.agent.md index 30f6b75..d88a3ea 100644 --- a/custom/agents/roemer.agent.md +++ b/custom/agents/roemer.agent.md @@ -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. diff --git a/custom/agents/smiley.agent.md b/custom/agents/smiley.agent.md index eec8abe..26824cc 100644 --- a/custom/agents/smiley.agent.md +++ b/custom/agents/smiley.agent.md @@ -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: ] → User confirms (the tier+route directly, or the Ergasterion's ruling if HIGH) → Code begins ``` diff --git a/custom/knowledge/architecture/task-state-lives-in-the-mandatory-artifact.md b/custom/knowledge/architecture/task-state-lives-in-the-mandatory-artifact.md index acad3d3..2682706 100644 --- a/custom/knowledge/architecture/task-state-lives-in-the-mandatory-artifact.md +++ b/custom/knowledge/architecture/task-state-lives-in-the-mandatory-artifact.md @@ -40,6 +40,8 @@ can drift; the artifact the flow already requires cannot drift from itself. ``` TASK_STARTED branch created, BC gitHubDevStatus = In Progress (PTE only) +ERGASTERION_RULING: PROCEED | PROCEED_WITH_CHANGES | RECONSIDER (HIGH tier only, + before implementation — see below) RED_CONFIRMED test written, developer confirmed the failing run GREEN_CONFIRMED test passes, developer/CI has actually run it REVIEW: APPROVE | APPROVE_WITH_NOTES | BLOCK al-review's verdict @@ -47,6 +49,22 @@ ON_HOLD parked mid-task (Focus gate) — always includes why MERGED track branch merged, BC Done (PTE) / PR merged (AppSource) ``` +**2026-08-03 — `ERGASTERION_RULING` carries required changes forward.** When +a HIGH-tier task convenes the Ergasterion (`ergasterion.agent.md`) before +implementation, its ruling — and, critically, the *exact required changes* +for a PROCEED_WITH_CHANGES or RECONSIDER disposition — is written into the +same trail, not just decided in the moment and forgotten. Without this, +nothing downstream (al-review, at merge time) has any way to check whether +the implementation actually honored a design ruling that happened before +code existed. The checkpoint text includes the required-changes list +verbatim, e.g.: + + [CURABIS-STATE] ERGASTERION_RULING: PROCEED_WITH_CHANGES — hide the + exchange-rate lookup behind an interface before implementation — 2026-08-03, mid + +al-review's Titus checklist reads this checkpoint back and treats an +unaddressed required change as a BLOCK finding — see `al-review.agent.md`. + ## PTE format — a tagged comment per transition Write one `[CURABIS-STATE]` comment per transition via `Create_TaskComment_PAG6102902` diff --git a/custom/setup/curabis-standard.agent.md b/custom/setup/curabis-standard.agent.md index 80adb99..5a40335 100644 --- a/custom/setup/curabis-standard.agent.md +++ b/custom/setup/curabis-standard.agent.md @@ -875,7 +875,20 @@ Guide administratoren gennem: 1. Invitér brugeren til organisationen som **member** 2. Giv **Read**-rolle på de valgte repos — aldrig Write/Maintain/Admin -3. Verificér at brugeren IKKE har adgang til `Curabis/QualityHub` +3. Verificér at brugeren IKKE har adgang til `Curabis/QualityHub` — og tjek + BÅDE vejene dertil, ikke kun den ene: (a) ingen direkte collaborator- + invitation til QualityHub, OG (b) brugeren er ikke medlem af et team der + selv har adgang til QualityHub (team-nedarvet adgang omgår en ren + per-repo-check), OG (c) organisationens "Base permissions" (Org Settings → + Member privileges) ikke er sat bredere end "No permission"/"Read" på en + måde der stiltiende dækker private repos. 2026-08-03: et tidligere audit + fandt at trin 3 kun tjekkede (a) — en bruger kunne i praksis få adgang via + (b) eller (c) uden at noget fangede det. +4. **Registrér onboardingen** i `custom/setup/support-users-onboarded.md` + (denne fil, append-only) — navn, GitHub-brugernavn, dato, tildelte repos. + Uden dette har intet senere trin (station 15 i Rømers runde) noget at + tjekke imod, og en glemt/forkert adgang forbliver usynlig for altid, ikke + kun til næste inspektion. ### Step 3 — Claude-miljø (browser, ikke VS Code) diff --git a/custom/setup/support-users-onboarded.md b/custom/setup/support-users-onboarded.md new file mode 100644 index 0000000..a41b399 --- /dev/null +++ b/custom/setup/support-users-onboarded.md @@ -0,0 +1,14 @@ +# Support users onboarded via Mode C + +Append-only registry of every Mode C (support-profile) onboarding — see +`curabis-standard.agent.md`'s MODE C section, Step 2.4. Never delete or edit +a row after the fact; if a user's access is later revoked or their profile +changes (e.g. promoted to full developer access), add a new row noting the +change rather than removing the original entry. This is what Rømer's +inspection round station 15 reads to periodically re-verify that every +support user still has no `Curabis/QualityHub` access and no Write+ role +anywhere — a registry with silently edited history defeats that check the +same way an edited `[CURABIS-STATE]` comment would. + +| Name | GitHub-brugernavn | Dato | Tildelte repos | Status | +|---|---|---|---|---| diff --git a/custom/setup/templates/HEARTBEAT.md b/custom/setup/templates/HEARTBEAT.md index b8c8613..4affe74 100644 --- a/custom/setup/templates/HEARTBEAT.md +++ b/custom/setup/templates/HEARTBEAT.md @@ -70,11 +70,15 @@ Tjek branches ældre end 14 dage uden åben PR. ### 6. Agent-synlighed i CLAUDE.md Sammenlign filer i `.github/.agents/` med referencer i `CLAUDE.md`. +Kald Rømer (`roemer.agent.md`) hvis 1+ agent i mappen ikke er nævnt i +CLAUDE.md — det er præcis hans station 8 (agent visibility), og han kan +afgøre om det er drift eller en legitim lokal afvigelse der skal videre +til Ferencz. | Klassifikation | Kriterium | |---|---| | Routine | Alle agenter er nævnt i CLAUDE.md | -| Concerning | 1+ agent i mappen er ikke nævnt i CLAUDE.md | +| Concerning | 1+ agent i mappen er ikke nævnt i CLAUDE.md — Rømer kaldt | --- diff --git a/custom/setup/templates/al-review.agent.md b/custom/setup/templates/al-review.agent.md index c4a3aff..8ec639e 100644 --- a/custom/setup/templates/al-review.agent.md +++ b/custom/setup/templates/al-review.agent.md @@ -1,7 +1,7 @@ --- kind: action-skill id: curabis-al-review -version: 3 +version: 4 title: CURABIS AL independent review (Torvalds & Winters) description: Independent per-change code reviewer. Runs after the TDD green gate and before merge — the fourth checkpoint, separate from the implementer and from portfolio-level rule governance (Rømer/Immanuel/Court, who ask "is the ruleset healthy", not "is THIS change good"). Two lenses - Linus Torvalds (BC/AL domain-technical correctness, backward compatibility, performance, security) and Titus Winters (general software-engineering maintainability, architecture, complexity over time). inputs: [diff, task-description] @@ -111,6 +111,18 @@ remember to request. See `smiley.agent.md`. `[[task-state-lives-in-the-mandatory-artifact]]`. This is a BLOCKing finding, not a note — the fix is trivial (go check what actually happened and record it truthfully), so there's no reason to let it slide. +- **Did the diff honor a prior Ergasterion ruling?** (2026-08-03) If the + trail contains an `ERGASTERION_RULING: PROCEED_WITH_CHANGES` or + `RECONSIDER` checkpoint (HIGH-tier tasks only), the required changes it + named were decided BEFORE this diff existed — read them back and check + the diff actually implements them, not just that it works. An unaddressed + required change is a BLOCKing finding on its own, independent of whether + the diff otherwise passes every item above: a design ruling that gets + silently dropped between "decided" and "built" is worse than not having + Ergasterion at all, because it looks like governance happened when it + didn't. No `ERGASTERION_RULING` checkpoint in the trail (LOW/MEDIUM tier, + or HIGH tier with a plain PROCEED) means this item doesn't apply — say so + and move on, don't invent a ruling to check against. ## Protocol diff --git a/custom/setup/templates/curabis-task-state-check.yml b/custom/setup/templates/curabis-task-state-check.yml index d6acf0d..10b17f0 100644 --- a/custom/setup/templates/curabis-task-state-check.yml +++ b/custom/setup/templates/curabis-task-state-check.yml @@ -1,11 +1,37 @@ name: CURABIS task-state check -# Deterministic enforcement (not LLM diligence) for the AppSource state-trail -# format from task-state-lives-in-the-mandatory-artifact.md. Parses the PR -# body for a "## CURABIS Task State" checklist and fails if any checked box -# appears AFTER an unchecked one - i.e. a later stage claimed without an -# earlier one. Silently passes (does nothing) if the section is absent - -# this check only applies to PRs that actually opted into the state trail; +# 2026-08-03 - scope correction after an audit found the header overstated +# this check's actual guarantee. +# +# What this DOES enforce deterministically: checklist ORDER in the PR body +# ("## CURABIS Task State") - a later stage cannot be checked while an +# earlier one isn't. It runs on every push/edit, needs no AI session to +# execute, and cannot be talked out of failing. +# +# What this does NOT enforce, and never has: that a checked box corresponds +# to a real event (a red test that actually ran, a review that actually +# happened). A session or a rushed developer can check every box in perfect +# order having done none of the underlying work, and this Action passes. +# The order check catches a narrower, still-real failure mode (a later +# stage claimed before an earlier one) - it is not proof the trail is true. +# +# This ALSO does not enforce anything by itself unless a human has +# separately added it as a required status check in the repo's branch +# protection settings (curabis-standard.agent.md documents this as a +# one-time manual step - it cannot be automated by file deployment). Absent +# that, a failing run just shows as a red X someone can ignore and merge +# past. Rømer's inspection round has a station that checks whether branch +# protection is actually configured this way - see roemer.agent.md station 14. +# +# This check ONLY covers the AppSource track (PR body checklists). The PTE +# track (BC task comments) has NO equivalent deterministic backstop - only +# Smiley's Close-gate self-verification and al-review's "state trail +# complete?" checklist item, both of which are an AI session re-reading its +# own/BC's history, not an independent script. That is a known, accepted +# gap, not an oversight - see task-state-lives-in-the-mandatory-artifact.md. +# +# Silently passes (does nothing) if the "## CURABIS Task State" section is +# absent - this check only applies to PRs that opted into the state trail; # it must never block an unrelated PR (docs fix, infra change, etc.). on: