Feedback
Walk the 14 architectural patterns one at a time and tell us which ones you would adopt — not which page confused you.
Copy the walk below into your own agent and run it. It measures your machine first, shows you the whole map and asks whether you want it, then takes the fleet’s 14 architectural patterns one at a time — explaining each pattern inside the question, with the real identifiers, the published failure modes and an explicit split of what transfers to other substrate and what does not. Then you decide, per pattern: research it against your infrastructure, go deeper, integrate it, or skip it.
It writes feedback.md at the end, and you drop that back here. The maintainers reverse-engineer this wiki from the outputs readers say they want, so the useful thing to send is what you are trying to get your setup to do — and a pattern you rejected, with the reason, is worth more than a vague endorsement.
You can stop part-way. A walk that covers four patterns and ends writes a four-pattern file, and that is a complete result rather than an abandoned one.
Step 1 · Run the walk
The pattern walk
Paste this into your own agent. It measures your setup, then walks you through the 14 architectural patterns one at a time — explaining each inside the question before asking what you want to do with it — and writes feedback.md in the directory you ran it from. It is long because each pattern carries the fleet’s real identifiers, its published failure modes, and what does not transfer.
You are running the Utopia Fleet Wiki PATTERN WALK for me (docs.utopiamodels.ai).
This is not a form. It is a guided walk through the 14 architectural patterns this fleet actually
runs on. You explain one pattern to me, then ask what I want to do about that pattern. At the end
you write a file I drop back on the feedback page.
THE ONE RULE, and it governs everything below:
Explain a pattern inside the question itself, then ask what to do about that pattern. NEVER ask
a question whose terms I have not just been given.
There is no strict set of questions. The strict set is the PATTERN INVENTORY — the 14 below. Every
pattern gets the same five-way decision, so I am never parsing a new question format, only new
subject matter.
WHY THIS FEEDBACK IS WANTED — read before you start, it changes what you listen for.
The wiki's maintainers reverse-engineer their documentation from the OUTPUT people say they want.
The valuable thing is not "page X confused me" — it is "here is what I am trying to get my AI setup
to DO", and, pattern by pattern, "this one I would adopt, this one I would not, and here is why."
A rejection with a reason is worth more than a vague endorsement.
"Architectural patterns" is the fleet's own decided term for these 14, not a synonym for
mechanisms, components or infrastructure. The reasoning is published at
https://docs.utopiamodels.ai/docs/structure/architecture#the-vocabulary — link me there if I ask; do not
restate the definition inside this interview, because then there are two definitions to keep true.
HOW TO ASK
Ask every question in this walk with your harness's own interactive question tool (Claude Code `AskUserQuestion` · opencode `question` · Codex CLI `request_user_input` · Gemini CLI `ask_user` · Cursor's built-in Ask-questions tool; Claude Desktop has none — write the option list out instead). One question at a time. Never more than one at once.
Never fill in an answer on my behalf. If your harness has no such tool, say so in one line and then
ask in plain text with the options written out and the recommended one marked — never drop the
options, because the recommendation is the whole reason the dialogue is worth using.
=============================================================================================
STEP A — MEASURE MY SETUP BEFORE YOU ASK ME ANYTHING
=============================================================================================
Do NOT ask me "what are you running today". A harness name with no context attached tells you
nothing, and the answer falls out of a properly-scoped look at my machine for free. Measure it.
Spend a few commands establishing, on THIS machine:
- Which agent harnesses are installed and configured, and how many. Look for more than one —
check for `claude`, `cursor`, `codex`, `gemini`, `aider`, `copilot` on PATH, and for their
config directories (`~/.claude`, `~/.cursor`, `~/.codex`, `~/.config/*`). Someone running
three side by side is a completely different reader from someone running one.
- Whether those harnesses share a skill/command/rule corpus or each keep their own copy, and
whether the copies have diverged. Diff them if there is more than one.
- The version control and tracker situation: how many repos, how many branches per ticket,
whether ticket state and merged branches agree, whether the tracker is reachable from here.
- What can schedule something: systemd timers, cron, launchd, Windows Task Scheduler.
- Whether anything agent-related stays resident between runs.
Report what you found in a short table before Q0, and say plainly which figures you could not
measure and why. Every later "where you stand today" line depends on this pass, and a guess here
poisons the whole walk. If a measurement is unavailable, the honest line is "not measured", never
a plausible number.
This pass gives you `harness` for the file at the end. Derive it; do not ask for it.
=============================================================================================
STEP B — QUESTION 0: CONSENT TO THE MECHANISM ITSELF
=============================================================================================
Show me the whole map and ask whether I want it, BEFORE any pattern is discussed. This interview
is a thing I can redesign, not a thing done to me. Ask exactly this:
Here are the 14 core architectural patterns. We are going to go one pattern at a time and dive
deep into each — I explain it inside the question, then you decide what to do with it.
1. Dispatch runtime — two scripts and a transient unit; nothing resident, and starting the run
IS the assignment
2. Scheduling / the sweeper — what finds work and starts it, and how it explains every issue it
refused
3. The queue — one tracker, routing by lane, and a status nobody types
4. Work lifecycle — PLAN / Feature / issue, and five steps that are derived rather than reported
5. Work artifacts — a committed brief beside the work, whose checkboxes ARE the live state
6. Mode and context switching — which harness, which model, which permissions, and what the
agent is allowed to see
7. Gates and merge policy — every check advisory, one hard stop, fix-forward, finish means merged
8. Communication — @mention on the work item and nothing else; presence derived, never
self-reported
9. Failure announcement — a failed run files its own issue within seconds; silence is the only
unacceptable outcome
10. Liveness vs existence — the account exists and the agent still cannot run a single turn
11. Surfaces and classification — every hostname carries a class, because a 404 has three meanings
12. Secrets — one store, a registry of what each credential MEANS, values on stdin never argv
13. Documentation architecture — generate the volatile, write the durable, serve agents a .md twin
14. Decision discipline — kill records, a never-resurrect list, and a limit that is a measurement
Each pattern gets the same five-way decision: research it against your infrastructure, explain it
in more depth, integrate it and start planning, skip it, or other. "Skip it" records two
different answers — you would not adopt it, or it is fine and you own nothing it acts on. Each
pattern has narrow sub-points inside it, and skipping a pattern skips all of them.
This is the default feedback interview mechanism. Let me know if you want to proceed with it —
this can change too, for professionalism or optimization.
1. Proceed with the default interview mechanism
2. Explain the interview process more in depth
3. Make slight changes to the interview process
4. Make major changes to the interview process
5. Other — free text
Option 2 loops back to Q0 with more detail — do not advance to pattern 1 on a request for more
explanation. Options 3 and 4 revise this walk before any pattern is walked: take the revision,
restate the revised walk back to me, and get agreement before starting.
=============================================================================================
STEP C — THE PER-PATTERN QUESTION
=============================================================================================
Each of the 14 briefs below carries five of the six parts you need. Part 5 is yours to measure.
Present them in this order, every time, so I always know where I am:
1. The header line, exactly: `PATTERN n of 14 — NAME (broad)`
2. WHAT IT IS — from the brief. Keep the real identifiers and real numbers; they are the point.
3. THE ARTIFACT — the verbatim log line, config fragment or command in the brief. Show it as
given. Concrete beats descriptive.
4. WHAT IT COSTS — from the brief. Never present a pattern as free. Every one of these has a
published failure mode and the brief carries it.
5. WHERE I STAND TODAY — YOU write this line, from your Step A measurements. Measured if
possible, and say so plainly if it is not. "I could not measure this" is a legitimate answer;
an invented number is not.
6. WHAT TRANSFERS AND WHAT DOES NOT — from the brief, split explicitly, on BOTH axes. Half of
these patterns depend on a dedicated server, multiple agent accounts, systemd, or a particular
plan tier: that is the SUBSTRATE axis. The second axis is OWNERSHIP — whether you own the
thing the pattern acts on at all. A pattern can transfer perfectly to your substrate and still
find nothing of yours to act on, and those are different findings. Step F's ledger keeps them
apart.
Then the decision, with the pattern name interpolated into every option label. A bare "explain in
more depth" reads as generic and I lose track of what I am deciding about:
What do you want to do with {pattern}?
1. Research {pattern} against my current infrastructure
2. Explain the Utopia pattern {pattern} in more depth
3. Integrate {pattern} — start planning it
4. Not integrating {pattern} — skip it
5. Other — free text
Options 1-4 are what the dialogue renders; option 5 is the free-text escape. Several harnesses add
that escape themselves rather than making you render it — if yours does, use the one it adds.
- Option 1 PAUSES the walk. See Step D. It is not a decision; the pattern is re-asked afterwards.
- Option 2 loops back to the SAME pattern with more depth. Do not advance.
- Options 3 and 4 are terminal for that pattern and advance the walk.
- OPTION 4 HAS TWO MEANINGS AND THE LEDGER KEEPS THEM APART. "I would not adopt this" is a
rejection of the pattern. "This is a good pattern and I own nothing it acts on" is NOT
APPLICABLE. Take the meaning from the reason I give; if the reason does not settle it, ask me
which — that one follow-up earns its place, because the two read identically in a ledger and
only one of them is feedback about the pattern. Do not add a fifth rendered option to fix this:
every one of these question tools caps at three or four rendered options, which is exactly why
option 5 is the free-text escape rather than a fifth choice.
BROAD PATTERN FIRST, THEN NARROW. Each brief lists the pattern's narrow points. Walk into them only
after I have adopted the broad pattern. A pattern rejected at the broad level SKIPS ALL of its
narrow points, and the log must say so rather than leaving them unanswered.
NAME DEPENDENCIES AS THEY ARISE. When a rejection makes a later pattern more expensive or
incoherent, say it once, in one sentence, and move on. Rejecting the dispatch runtime leaves
scheduling with nothing defined to start — that is worth one line before the next question, not a
paragraph, and not repeated.
I MAY STOP EARLY. If I end the session part-way, that is a complete result, not an abandoned one.
Write the file with what was walked and record the rest as "not walked". Do not talk me into
finishing all 14.
=============================================================================================
STEP D — THE RESEARCH PROTOCOL (MANDATORY)
=============================================================================================
When I pick "Research {pattern} against my current infrastructure":
1. DISPATCH SUBAGENTS. One per measurement area. Do not perform the research inline in the main
thread when subagent dispatch is available to you.
2. TELL ME YOU ARE WAITING. State plainly that subagent research is running and that you are
waiting on it.
3. DO NOT SKIP AHEAD. Do not ask the next question, do not move to the next pattern, and do not
start speculating about the result while the subagents are out.
4. RE-ASK THE SAME PATTERN once the findings return, with the numbers folded INTO the question
body — not appended after it. Then I decide.
Every subagent brief must demand a measurement WITH the command or file path that produced it. A
subagent that returns an impression instead of a measurement has not answered; send it back.
FALLBACK, AND BE HONEST ABOUT INVOKING IT. If subagent dispatch fails for reasons outside your
control — provider overload, a harness without subagents, a quota refusal — do not retry the
fan-out. Fall back to sequential measurement yourself, and SAY IN THE FILE that you did and why.
This clause is not hypothetical: in the run that designed this walk, subagent dispatch failed 13
times out of 13 with `API Error: 529 Overloaded`, across two separate prompts, and both research
passes were completed inline as a result.
=============================================================================================
STEP E — THE 14 PATTERN BRIEFS
=============================================================================================
Ordered by dependency: what executes a run, before what routes to it, before what shapes it,
before what surrounds it. Every number below was measured by the fleet on the date given. Quote
them as dated evidence, not as a live reading.
---------------------------------------------------------------------------------------------
PATTERN 1 of 14 — DISPATCH RUNTIME (broad)
Narrow points: 1.1 no resident process · 1.2 start-is-assignment · 1.3 pre-flight gates ·
1.4 detached execution · 1.5 close-out markers · 1.6 attempt caps and concurrency
---------------------------------------------------------------------------------------------
WHAT IT IS. Two shell scripts and systemd. That is the entire agent runtime — no scheduler daemon,
no queue service, no watchdog, and no agent process resident between runs.
`_infra/scripts/dispatch.sh <master> <issue#> [repo]` hands a master its issue BY STARTING THE RUN;
there is no separate claim step. `_infra/scripts/task-runner.sh <issue#> [repo]` is the run itself,
on the master's own box. One dispatch reaches the box with one `ssh nova@100.71.25.43` plus
`sudo -u <master>`, runs three pre-flight guards (quota-dark master, duplicate run on that box,
and a lock-held fleet-wide claim), launches a detached transient unit, and returns. The run posts `▶ started` on
the issue before anything that can fail, then `claude -p --max-turns 200`, and its exit trap posts
`✔`, `✘`, `⚠` or `⛔` with the pull-request link.
THE ARTIFACT.
systemd-run --user --unit=task-<issue> --collect
That `--collect` and `--user` pair is why a run survives the SSH connection dropping and the
laptop going to sleep. The run's own `▶` and `✔` comments on the issue are the fleet's entire
definition of liveness — there is nothing else to ask.
WHAT IT COSTS.
- The pre-flight gates fail OPEN on purpose. An unreadable state file, a missing file, or a reset
time already in the past all mean "not dark", because a false block stops the fleet and that is
worse than one wasted run. You are choosing wasted runs over stalls, deliberately.
- A guard in only ONE consumer cannot see the other path. The "one issue, one run" check has to
live in the entry point that the scheduler and a hand-typed dispatch both share.
- "Nothing resident" is a claim about the RUNTIME, not about the box, and the two get confused —
including by readers running the walk from inside this fleet. No dispatched run leaves a process
behind; a master's own standing interactive session is a different thing and can sit in tmux for
weeks (measured on one master, 2026-08-23: an agent process resident 13.3 days). If you adopt
this pattern, adopt the precise claim, and write down the sanctioned exceptions next to it —
otherwise the first person to run `ps` concludes the published property is false.
- The last-moment disposal race is real and was measured: pre-flight read the issue at 14:36:01
and it was open and correct; it was labelled a throwaway at 14:36:03 and closed at 14:36:05;
systemd started the unit at 14:36:12; `▶` posted at 14:36:15. A master then spent a full
session on board residue. Every gate that asks "is this still work" runs too early unless it
runs from INSIDE the run, immediately before `▶`.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: start-is-assignment, nothing resident, and close-out markers posted by an exit trap.
All three are policy and cost nothing but discipline.
Does not: the mechanism needs systemd `--user`, several unix accounts on one box, and `sudo -u`
between them. On a single Windows workstation with one user account there is no `sudo -u` and no
transient unit — the equivalent is a detached process plus Task Scheduler, and per-agent identity
has to come from somewhere other than the OS.
---------------------------------------------------------------------------------------------
PATTERN 2 of 14 — SCHEDULING / THE SWEEPER (broad)
Narrow points: 2.1 timer-riding vs a dedicated service · 2.2 the eleven predicates ·
2.3 `--explain` as diagnostic · 2.4 single-homed scheduling risk
---------------------------------------------------------------------------------------------
WHAT IT IS. The thing that carries a chain of work forward is NOT a service and NOT a cron job. It
rides as the second `ExecStart` line of a systemd drop-in on one master's `reconcile-board.service`,
fired by `reconcile-board.timer` every five minutes. It reads the board, applies a fixed set of
predicates to every open issue, and dispatches whatever survives them.
THE ARTIFACT.
/home/nova/.config/systemd/user/reconcile-board.service.d/10-sweep-dispatch.conf
ExecStart= (clear)
-/usr/bin/bash %h/.claude/ops/reconcile-board-status.sh --apply
-/usr/bin/bash %h/dev/utopia-models/knowledge/_infra/scripts/sweep-dispatch.sh --apply
-/usr/bin/bash %h/.claude/ops/mute-agent-notifications.sh --apply
Its log line is the best one-line health summary the fleet produces. Emitted 2026-09-04T08:48:34Z:
sweep: 39 open · 0 dispatchable · in-flight 3 (win=2 nova=0 cloud=1 dust=0 )
A refused master appends a trailing `· rate-limited: (exhausted <name>)` segment; it is absent above
because every master was clear on that pass.
And the diagnostic that makes it debuggable, which prints a reason PER ISSUE:
# on novaserver, from the knowledge clone
bash _infra/scripts/sweep-dispatch.sh --explain
Each rejected issue prints its own reason: `lane-not-in-masters`, `has-hold-label`,
`is-a-grouper:has-open-subissues`, `last-marker-is-terminal`, `parent-closed`, `is-parked`.
WHAT IT COSTS.
- Timer-riding makes the scheduler INVISIBLE to any probe that looks for it by name. Every check
that goes hunting for a `sweeper.service` falsely reports it missing.
- Scheduling is single-homed. Measured 2026-08-16: 35 timers on one master's user manager against
2 each on two others and 1 on the fourth. One box's user manager is the fleet's cadence.
- Cron is a second, parallel scheduling layer. Masters carry crontab entries with no systemd timer
at all, so an audit reading only `systemctl --user list-timers` under-reports every master.
- A dead timer never fails, so `systemctl --failed` reports clean on a broken box. The box has
held an ENABLED timer whose service unit was `not-found` while every failure query returned
empty.
- `39 open · 0 dispatchable` looks like a capacity failure and is a ROUTING failure. The sweeper
had been printing the cause every five minutes while investigations went looking for a bug.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: `--explain` — a scheduler that prints, per item, the named predicate that rejected it.
That is the highest-value line in this whole pattern and it works on any scheduler you own.
Does not: timer-riding is a systemd trick and a liability. On Task Scheduler or launchd, a
dedicated entry is clearer and the invisibility cost is not worth copying.
---------------------------------------------------------------------------------------------
PATTERN 3 of 14 — THE QUEUE (broad)
Narrow points: 3.1 one tracker only · 3.2 lane as routing, unrouted = invisible ·
3.3 portfolio as grouping · 3.4 derived vs typed status
---------------------------------------------------------------------------------------------
WHAT IT IS. There is exactly ONE tracker: a GitHub organization project board. Every open issue in
the knowledge repository is on it — measured 2026-08-16, zero off-board work existed. Work that
becomes a board issue lives on the board and nowhere else; it specifically does not also live in an
agent harness's private to-do list, because two trackers cannot both be true. Each row carries the
issue, its LANE (which master serves it), a PRIORITY, a PORTFOLIO, and a STATUS that is derived
rather than typed.
THE ARTIFACT. The negative property is the important one, and it has a name in the sweeper's own
output:
lane-not-in-masters
An issue with no lane, or on a lane no master serves, is structurally undispatchable —
permanently, silently, and regardless of how idle the fleet is. Measured 2026-08-16: of the open
issues at that moment, thirteen were undispatchable — eleven with no lane at all, plus two on a
lane no sweeper reaches.
WHAT IT COSTS.
- Nothing rejects a row with no lane and no status at creation time, and a row in that state is
invisible to routing. The queue's worst failure mode is silent by construction.
- Closed rows from other repositories never converge: the reconciler archives rows only for the
repository it runs in, so closed items from sibling repos accumulate. On 2026-08-16 they were
the MAJORITY of all rows on the board.
- And the honest one, which the fleet publishes about itself: doctrine says "the board is the
ONLY tracker" and also "the plan.md checkboxes ARE the work state". Counting honestly there are
FOUR parallel trackers for one body of work — the board, a plan registry, the plan documents,
and the per-spec checkboxes. Plan documents exist with no registry entry, which makes them
invisible to the command center, which reads only entries.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: one canonical tracker, and derived rather than typed status. Both are decisions, not
infrastructure.
Does not: "lane" needs a board with a custom routing field and an API a scheduler can read. If
your tracker is a corporate one that is blocked at the network level from the network you do
infrastructure work on, then "read scope live from the ticket" cannot hold there at all, and this
pattern has to be rejected or redesigned around an offline cache — say which.
---------------------------------------------------------------------------------------------
PATTERN 4 of 14 — WORK LIFECYCLE (broad)
Narrow points: 4.1 the three words and the retired fourth · 4.2 five derived steps ·
4.3 step-4 mode · 4.4 "stuck" is a comment, not a state
---------------------------------------------------------------------------------------------
WHAT IT IS. Three layers, three words, and a deliberately retired fourth. A PLAN (`PLAN-178`) is one
thinking session: a document, its research, and the forks it closed — it lives ABOVE the board. A
Feature (`#5878`) is a body of shippable work with ordered children. An issue (`#5882`) is one
dispatchable unit run to a merged pull request. A PLAN is not a Feature: it references Features and
can spawn several, and some of what a PLAN decides never becomes work at all. The fourth word,
"task", was retired because it named two of these at once.
THE ARTIFACT.
1 BRIEF · 2 LOOP ⟳ ‖ 3 FILE · 4 DISPATCHED · 5 DONE
Every step is DERIVED, never reported. Steps 3-5 are read off the board on every render; steps 1-2
come from events on the plan's own entry. Nothing anybody WRITES advances a step — a merged pull
request does, by closing an issue. There is no status field for a human to set, which means there
is no status field for a human to forget. Step 4 carries a mode and neither value is "blocked":
`DISPATCHED` (unattended) or `EXECUTING (interactive)` (a human in the loop, but not blocking it).
WHAT IT COSTS.
- Being genuinely stuck is not a state. It is a comment on the issue saying exactly what blocks
you, followed by a clean exit — which means a stuck item looks identical to a running one unless
somebody reads comments. Stopping silently is the one unacceptable outcome, and nothing
structurally prevents it.
- Derived status means you cannot annotate a state the board cannot compute. You trade
expressiveness for the impossibility of a stale status field.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: the three words, the retired fourth, and derived-not-typed status. This is the pattern
most often adopted on foreign substrate, because it is entirely vocabulary and discipline.
Does not: "a merged pull request moves the board" needs the tracker and the VCS to be the same
system, or a webhook between them. If your tickets live in a tracker your git host cannot close,
the derivation has to be built, and until it is, both signals drift. That is measurable, and the
contrast is the whole reason this pattern is worth deciding on: ON THE READER'S MACHINE in the run
that designed this walk — a Windows workstation with a corporate tracker, NOT the fleet — ZERO of
14 ticket branches had merged to their default branch, while ticket state had moved anyway, by
hand, through five typed states. On the fleet the same measurement runs the other way. Measure
YOUR side before deciding; neither number is yours until you have.
---------------------------------------------------------------------------------------------
PATTERN 5 of 14 — WORK ARTIFACTS (broad)
Narrow points: 5.1 thick tasks · 5.2 checkboxes as live state · 5.3 the issue must name the spec
path · 5.4 decision records and `Superseded-by`
---------------------------------------------------------------------------------------------
WHAT IT IS. A dispatched issue is not a sentence. The brief lives BESIDE the work, in the repo.
THE ARTIFACT.
<portfolio>/specs/<issue#>-<slug>/spec.md objective · acceptance · scope · grounding
<portfolio>/specs/<issue#>-<slug>/plan.md phases → checkbox items
The `plan.md` checkboxes are the LIVE WORK STATE. Tick `[ ] → [~] → [x]` and commit as you go. This
is not a report written afterwards: a context reset, a peer taking over, and the founder looking in
all read that same file. It has been proven — one master's capped run was finished by a different
master from that file alone.
WHAT IT COSTS.
- The issue body must contain the LITERAL spec path. A runner reads a spec only if the issue names
one, so an unnamed spec does not exist to the master executing the work. It is the
highest-leverage line in the pipeline and the easiest to omit.
- A spec can cite dead machinery in perfectly good faith, so every reference has to be re-grounded
in the session that acts on it. If the prerequisites are dead, the correct move is to stop
cleanly and say why on the issue — never churn a stale brief.
- Superseding a decision record edits the old record's `Superseded-by` header IN THE SAME COMMIT.
A silently invalidated decision record is this fleet's most repeated failure.
- Honest cost: `plan.md` is one of the four parallel trackers named in pattern 3. This pattern and
"one tracker only" are in genuine tension and the fleet has not resolved it.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: all of it. It needs a repository and nothing else — no server, no accounts, no systemd.
Does not: nothing, structurally. The cost is purely the discipline of writing the brief before
dispatching, which is where it usually fails.
---------------------------------------------------------------------------------------------
PATTERN 6 of 14 — MODE AND CONTEXT SWITCHING (broad)
Narrow points: 6.1 work-state mode · 6.2 harness/model/permission mode · 6.3 context scope
---------------------------------------------------------------------------------------------
WHAT IT IS. Three axes that are usually conflated. WORK-STATE mode is what the agent is doing:
planning with a human in the loop, or executing unattended — the fleet spells this as step 4's
`DISPATCHED` vs `EXECUTING (interactive)`. HARNESS/MODEL/PERMISSION mode is which binary, which
provider and what the agent is allowed to do without asking; the fleet passes the BACKEND to every run
at dispatch time rather than reading it from a local settings file, which is why a master's provider can
be changed for the whole fleet without touching a single box. There is one provider today — every master
runs the same harness on a Claude subscription — and that is a decision, not a limitation of the shape. CONTEXT SCOPE is what the agent is allowed to see, and the fleet fixes it as
an ORDER rather than a pile.
THE ARTIFACT. The grounding order, run at the start of every dispatched run:
repo root CLAUDE.md → the portfolio's CLAUDE.md → the issue + its spec → the real files
Six unix accounts run agents — five on the server, one on the laptop — each with its own credentials,
its own `~/.claude` brain directory (each one a version-controlled repo of its own) and its own
GitHub identity. They are peers; there is no supervisor process.
WHAT IT COSTS.
- There is exactly ONE backend and nothing to fall back to. The launcher passes a literal provider
name to every run; the per-agent selection this fleet used to have was deleted along with the
alternate provider. When an agent's entitlement goes, its work waits. The dark-agent guard reads
a `quota-status.json` a newly-broken agent may never have written, and it FAILS OPEN — so a
dispatch into a dead agent is possible by design, on the grounds that a false block is worse.
- This is the thinnest of the 14 in the fleet's own documentation. Work-state mode is written down
precisely; permission mode is largely convention. If you adopt it you are extending it, not
copying it.
- The classic failure on a multi-harness machine: two or three harnesses each keeping their own
COPY of the same skill or rule corpus, every pair already diverged, so the same command means
different things depending on which one you are in — and nothing detects that.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: the grounding ORDER, and the discipline of naming which of the three axes you are
switching. Both are free.
Does not: the single-backend simplicity, which is a consequence of one flat subscription per agent
rather than a design win. Pay per token, or run two providers, and you need the selection logic
this fleet deleted — and you own its failure modes with it. And if you launch by clicking an icon
there is no launcher to read anything at start time: the mode is whatever the config file says,
which is the divergence problem above rather than a solution to it.
---------------------------------------------------------------------------------------------
PATTERN 7 of 14 — GATES AND MERGE POLICY (broad)
Narrow points: 7.1 advisory vs blocking · 7.2 the one hard stop · 7.3 fix-forward ·
7.4 finish means merged
---------------------------------------------------------------------------------------------
WHAT IT IS. NOTHING gates `main`. Branch protection and rulesets both return 403 on this GitHub plan
tier, in every repository. That is not a loophole being exploited — it is the actual configuration,
and the process is built to be honest about it. Therefore a check that is red, missing, or never
started is INFORMATION, never a stop. Fix-forward is the rule: identify the real failure, fix a
broken build or a genuine security finding, and use the documented fallback when infrastructure is
merely down. Finish means a pull request whose body says `Closes #N`, MERGED. Arming auto-merge is
not finishing — fifteen pull requests once stacked up unnoticed behind exactly that misunderstanding.
THE ARTIFACT.
gh pr merge <n> --squash --admin
And the one binding check, run locally when the workflow itself cannot start:
VERSION=8.24.3
curl -sL "https://github.com/gitleaks/gitleaks/releases/download/v${VERSION}/gitleaks_${VERSION}_linux_x64.tar.gz" \
| tar xz -C /tmp gitleaks \
&& /tmp/gitleaks git . --no-banner --redact --config .gitleaks.toml \
--log-opts "--no-merges <base>..<head>"
WHAT IT COSTS.
- "Nothing gates main" is a CONSEQUENCE OF A PLAN TIER, not a virtue. Read it as an honest
description of a constraint the fleet decided to build on rather than a recommendation.
- Two gate designs are forbidden outright because both were tried: a gate that blocks on content
keywords, and a gate built on a generated map. The second one false-blocked documentation
changes and AUTO-REVERTED ITS OWN CLEANUP; eighteen dead gate workflows went in one commit.
- The one hard stop — never a secret in a tracked file — is the only thing here that is not
fix-forward, not advisory and not overridable.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: fix-forward, "finish means merged", and refusing to treat a lint on a title or a
filename as a blocker.
Does not: reject this pattern outright if you have real branch protection, a compliance
requirement, a provenance constraint, or code review as a policy. "Every check is advisory" is
load-bearing on a fleet where a merge is git-reversible and one person owns everything. It is
actively wrong where a merge ships to someone else's production.
---------------------------------------------------------------------------------------------
PATTERN 8 of 14 — COMMUNICATION (broad)
Narrow points: 8.1 @mention as the only channel · 8.2 unread injection at run start ·
8.3 presence derived, never self-reported
---------------------------------------------------------------------------------------------
WHAT IT IS. Masters talk to each other by @mentioning a GitHub account in a comment ON THE RELEVANT
ISSUE. That is the whole mechanism. A master's next dispatched run receives unread mentions injected
at start, which gives at-least-once delivery with a durable read state, and it happens on the
surface the founder is already looking at. There is no chat system, no message bus and no inbox
service. There WAS a NATS bus; it was deleted, and it is on the never-resurrect list.
THE ARTIFACT. From the fleet's own decisions page:
Killed: the NATS message bus
`nats.service` and its reload units are on the never resurrect list. Three zombie units
survive on the box, and one of them is active.
Presence is derived from observable work — a last commit, a last comment — and never self-reported.
A heartbeat an agent writes about itself is a claim, not evidence. That is the rule for whether WORK
is alive. It is not the whole picture on the box, and the fleet does not publish only the flattering
half: a reader who runs the walk from inside this fleet finds a `*/5 * * * *` cron entry on a
master's own crontab POSTing that master's status to the command centre with a five-minute TTL as
the online/offline signal (`fleet-self-report.sh`, sanctioned 2026-07-22). It answers a different
question — which box is online for a human's dashboard right now — and it is never what tells you a
run finished. Adopt the rule, and know that the exception exists and is named.
WHAT IT COSTS.
- Delivery lands on the NEXT DISPATCHED RUN. A master that is never dispatched never reads its
mail, so an urgent message to an idle or quota-dark agent sits unread indefinitely. There is no
synchronous channel at all, by design.
- Everything is public. This composes with the fleet's standing "publish everything, unsanitized"
decision; on a machine with a provenance or confidentiality constraint it composes with nothing.
- Deleting the bus left THREE zombie units on the box, and the count in this fleet's own
published decisions page said two until a reader ran the command (knowledge#6665). Worse than
the count: one of the three is a `.path` unit that is `enabled` and `active (waiting)` — still
watching for changes to the config of a service that will never start again. A deletion in a
repo is half a deletion, and the surviving half keeps a timer running.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: comms on the work item rather than beside it, and presence derived from observable
work. Both are free and both survive any substrate.
Does not: unread-injection-at-run-start needs a launcher that reads your mentions API and a
durable read state per agent. If your tracker is unreachable from the network you work on, this
pattern has no delivery path at all and you should say so rather than adopting it aspirationally.
---------------------------------------------------------------------------------------------
PATTERN 9 of 14 — FAILURE ANNOUNCEMENT (broad)
Narrow points: 9.1 `OnFailure` → board issue · 9.2 silence as the only unacceptable outcome ·
9.3 the broken-notifier hole
---------------------------------------------------------------------------------------------
WHAT IT IS. When any user unit fails, systemd's `OnFailure` path upserts ONE board issue about it.
The system is not designed to avoid failure; it is designed so a failure announces itself within
seconds, on the surface a human already reads. Silence is the only unacceptable state.
THE ARTIFACT. Measured 2026-08-16, over the preceding 24 hours:
~157 dispatch runs · 2 failed · both failures filed their own board issue automatically
WHAT IT COSTS.
- The broken-notifier hole: the notifier itself failing is the one failure that cannot announce
itself. Nothing watches the watcher, on purpose, because a watcher-watcher is the resident
process this whole architecture deleted.
- A dead timer never fails, so `systemctl --failed` reports clean on a box holding an enabled
timer whose service unit is `not-found`. Absence of failure is not presence of function; you
have to enumerate the timers themselves and read the last and next columns.
- Deleting a scheduled unit from an agent's brain repo does NOT stop it running —
`~/.config/systemd/user/` holds COPIES, not symlinks. One such half-deletion left a timer
`active waiting` against a script that no longer existed; the next firing, nearly three hours
later, exited `203/EXEC` and filed a P0 about itself.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: the principle, entirely — a failure must produce a durable record on the surface a
human already reads, and the record must be an upsert so a flapping job files one item, not five
hundred.
Does not: `OnFailure` is a systemd feature. Task Scheduler has an on-failure action but no
upsert semantics, and launchd has neither — you write that half yourself.
---------------------------------------------------------------------------------------------
PATTERN 10 of 14 — LIVENESS VS EXISTENCE (broad)
Narrow points: 10.1 the distinction · 10.2 entitlement capture as evidence ·
10.3 naming the command that settles it
---------------------------------------------------------------------------------------------
WHAT IT IS. The most important distinction the fleet publishes. An agent can hold a valid unix
account, a present credential file, a clean systemd state and working `gh` auth, and still be unable
to run a single turn — because entitlement lives with the account AT THE PROVIDER, not on the box.
The registry's own check for an agent is `getent passwd <name>`, and that check PASSES on an agent
that cannot execute anything. When it happens the agent looks BUSIER than a healthy one: transient
units keep starting, keep dying in seconds, and keep announcing themselves.
THE ARTIFACT. The command that actually settles it, and the state file that records the refusal:
# on novaserver — the real probe. Anything other than a normal completion is the finding.
sudo -u nova -H claude -p 'reply with the single word: alive'
# on novaserver — what the agent itself last recorded
sudo -u nova -H cat /home/nova/.claude/state/quota-status.json
Measured 2026-08-16: three of the four masters could actually run, and the fourth reported
`{"exhausted": true, "resetsAt": null}` in its own state file. The `null` is the important half —
the provider named no recovery time, so no timer brings that agent back on its own.
WHAT IT COSTS.
- Naming the command that settles a claim is real work per claim, and it has to be RUN, not
documented. The fleet audited its own component registry and found that the `verify:` command on
every entry is "read by humans and executed by nothing", and that it records no box — so a
quarter of the commands fail from the wrong machine and pass from the right one.
- Exercising an artifact costs a real invocation. A probe that runs a turn spends quota to learn
whether it has quota.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: all of it, and this is the single most portable pattern in the inventory. It is a
discipline — for every health claim, name the command that settles it, run it, and record the box
it ran on.
Does not: nothing. The specific commands are fleet-shaped; the distinction is universal.
---------------------------------------------------------------------------------------------
PATTERN 11 of 14 — SURFACES AND CLASSIFICATION (broad)
Narrow points: 11.1 the four classes · 11.2 a checker that re-measures the doc
---------------------------------------------------------------------------------------------
WHAT IT IS. A status code is not a state. Two hostnames returning an identical 404 can mean
completely different things, so every hostname the fleet owns or references carries a CLASS, and the
class is the durable fact — the status code is evidence for the class, not a substitute for it.
THE ARTIFACT. The four classes:
LIVE intended to serve, and serving
RETIRED-BY-DECISION not serving, and that is CORRECT — a human decided, and the decision is
sourced. Do not "fix" one of these.
BROKEN not serving, and nothing says that was intended. The only class that is a bug.
NEVER-EXISTED appears in the fleet's own documents and has never resolved in DNS. Not a
surface — a citation of one.
Collapsing that distinction into a single "404" cell cost a P0: a master was dispatched to "restore"
a surface that had been deliberately retired ten days earlier, and it did exactly as it was told.
And the check, which is the second half of the pattern:
curl -s -o /dev/null -w '%{http_code} redirects=%{num_redirects} final=%{url_effective}\n' -L https://<host>/
WHAT IT COSTS.
- A dated table decays, so it needs a CHECKER rather than a promise. The fleet's reads the rows
out of the published page and re-measures every host, which means adding a surface adds a check
with no second edit. It has caught two rows so far — one recorded 200 when its root is a
redirect, one that went stale because the world moved.
- A 200 does not prove a page is public, and neither does `redirects=0`. An app that renders its
login IN PAGE answers 200 with redirects=0 and is completely gated. A stranger's agent read the
fleet's own rule correctly and concluded from `200 redirects=0` that the secret store was open
to the world.
- A hostname with no registry row cannot be monitored, so it cannot be noticed. Several LIVE rows
have no registry entry — including one serving on the company's own domain.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: entirely, ON SUBSTRATE. Four classes and a checker that re-measures the document need
nothing but a list and a shell.
Does not: nothing about your substrate — and this is the pattern most often rejected on the OTHER
axis. It classifies hostnames, so it needs you to OWN some. A reader holding no DNS, no registrar
credential and no row in a surface registry can run the checker against somebody else's host —
`curl -s -o /dev/null -w '%{http_code}' https://docs.utopiamodels.ai/llms.txt` returns 200 from
anywhere — and still learn nothing about an inventory of their own. Running one other party's
checker is not owning a classified inventory. That is NOT APPLICABLE, not a rejection, and the
ledger in Step F distinguishes them. Measured by the walk's own first field run: a dispatched
agent with no surfaces of its own reached exactly this conclusion (knowledge#6665, 2026-08-23).
---------------------------------------------------------------------------------------------
PATTERN 12 of 14 — SECRETS (broad)
Narrow points: 12.1 one store · 12.2 the registry of credential *meaning* · 12.3 stdin-not-argv
---------------------------------------------------------------------------------------------
WHAT IT IS. Infisical, self-hosted in Docker on the server, is the ONLY secret store. No local vault,
no `.env` checked in anywhere, no second store. A separate registry carries each credential's
MEANING — which account it belongs to, what scopes it has, what it can do and what it explicitly
cannot — so "I don't have access" is a claim that must be checked against a list before it can be
made.
THE ARTIFACT.
# read one value (never echo it)
V=$(bash ~/.claude/scripts/infisical-get.sh fleet-infra SOME_KEY prod); echo "len=${#V}"
# list every key in a project, so "it does not exist" is a real claim
bash ~/.claude/scripts/infisical-get.sh --keys fleet-infra prod /
# write a value; the value goes on STDIN, never in argv
printf '%s' "$NEW_VALUE" | bash ~/.claude/scripts/infisical-set.sh fleet-infra SOME_KEY prod
Passing a secret as an argument is rejected by a guard, because argv lands in shell history and in
the process table.
WHAT IT COSTS.
- One store is one single point of failure, self-hosted on the same box as everything else.
- The recurring failure is NOT a missing credential — it is a grep for the wrong key name. That is
why `--keys` exists and why listing the whole project is a standing rule before declaring
anything absent.
- Never print a secret, or the PRESENCE of one, to a display sink. Capture into a variable and
check its length. That constraint reaches further than people expect: it rules out most obvious
debug output.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: all three narrow points. Substitute any single store — 1Password, Vault, a cloud
secrets manager, the OS keychain. The registry-of-meaning is a plain file and is the half most
people skip and most need.
Does not: self-hosting needs a box that stays up. On a single workstation the OS keychain is the
better single store and the pattern is otherwise identical.
---------------------------------------------------------------------------------------------
PATTERN 13 of 14 — DOCUMENTATION ARCHITECTURE (broad)
Narrow points: 13.1 generate the volatile, write the durable · 13.2 request-time, no store ·
13.3 `.md` twins for agents · 13.4 organise by question, not component
---------------------------------------------------------------------------------------------
WHAT IT IS. Split every documented fact into VOLATILE (changes without anyone deciding it — a
status code, a count, a disk figure) and DURABLE (a method, a decision, a policy). Write the
durable. Generate the volatile, at request time, with no store: this wiki's live page states
`store: none — no snapshot file, no cache, no revalidate window`, and two fetches a second apart
show its `generated:` stamp advancing. Serve agents a plain-text twin of every page, and organise
pages by the QUESTION a reader arrives with rather than by component.
THE ARTIFACT.
curl -s https://docs.utopiamodels.ai/llms.txt | head -3
`/llms.txt` indexes every page; `/llms-full.txt` is the whole corpus in one fetch. Every docs page
has a `.md` twin at the same path, so an agent never has to parse HTML.
WHAT IT COSTS.
- The diagnosis that produced this pattern is not flattering: this site carried ~10% of the
fleet's knowledge base and derived from NONE of it — six hand-typed pages against a ~1.05 MB
corpus — and three days after its last edit, 17 of its 162 checkable claims were already false.
The page with ZERO false claims is made of method and policy. The page with one GENERATES ITS
OWN CHECK. That is this pattern arriving as a diagnosis rather than a theory.
- Request-time generation means the page is only as available as its upstreams. The honest design
reports failure PER SECTION — a line beginning `ERROR:` inside the page is that page reporting
an upstream it could not reach, which is data, not a broken fetch.
- A promise scoped to one path is a promise a reader will generalise. This site's zero-byte-404
promise is scoped to `/docs/`, and the first top-level page to break the pattern returned 10,514
bytes of HTML error page straight into an agent's context.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: entirely, and it is the pattern most likely to pay for itself immediately. The volatile
/ durable split needs no infrastructure — it is a question you ask of each sentence you write.
Does not: request-time generation needs a server that can read your sources at request time. A
static site generator gets you the `.md` twins and the durable/volatile split but not `store:
none` — there, the volatile facts belong behind a command the reader runs, printed verbatim, and
NOT as a number the page did not measure.
---------------------------------------------------------------------------------------------
PATTERN 14 of 14 — DECISION DISCIPLINE (broad)
Narrow points: 14.1 kill records · 14.2 never-resurrect · 14.3 `Superseded-by` in the same commit ·
14.4 a limit is a measurement
---------------------------------------------------------------------------------------------
WHAT IT IS. The fleet's most expensive recurring failure is re-deciding something that was already
decided and paid for. So every killed thing gets a record saying what it was, why it died, and what
replaced it; a NEVER-RESURRECT list names what may not come back; a decision is reopened only by a
superseding record that names what changed, with the original's `Superseded-by` header updated IN
THE SAME COMMIT; and no ceiling is set without the measurement written next to the number.
THE ARTIFACT. The never-resurrect list, verbatim:
- ralph and every watchdog, heartbeat and supervisor built to babysit it.
- The NATS bus and its three remaining zombie units.
- The generated component catalog and any fail-closed gate built on a generated map.
- Content-keyword gates of any kind.
- Resident processes, heartbeat polls and scheduled health checks as a way of knowing whether
the fleet is alive.
And 14.4, measured: the dispatch scheduler ran for days at roughly 8% OF PROVEN CAPACITY — three of
four masters idle on a 12-core box under a load average below 1 — because caps of 1, 4 and 2 had
been set against a failure mode two other mechanisms already covered. The defence was real; it was
aimed at the wrong axis. A cap chosen out of caution silently BECOMES the system's capacity, and
unlike a bug it never announces itself: it reports success while doing a fraction of the work.
WHAT IT COSTS.
- A silently invalidated decision record is WORSE THAN NONE, so the `Superseded-by` edit is not
optional bookkeeping — it is the whole mechanism.
- A name outliving its system keeps costing you, and it took two deletions here to stop. After the
resident loop was deleted, the registry kept a per-agent field named after it, described as the
live backend selector — and the FIELD really was read, so nobody could call it dead. The framing
outlived the system, then the field outlived the framing. Every reader in between had to work
that out for themselves.
- Writing the measurement next to every ceiling is slower than picking a number.
WHAT TRANSFERS AND WHAT DOES NOT.
Transfers: entirely. All four narrow points are text files and a habit.
Does not: nothing. This is the cheapest pattern in the inventory to adopt and the one most often
skipped, because its whole payoff is an argument you do not have six months from now.
=============================================================================================
STEP F — CLOSING
=============================================================================================
When the walk ends — all 14, or wherever I stopped — do these four things IN ORDER.
FIRST, show me the decision ledger. One row per pattern, in order, with one of FOUR decisions:
INTEGRATE I am adopting it.
NOT INTEGRATING I would not adopt this pattern. This is feedback ABOUT THE PATTERN.
NOT APPLICABLE The pattern is fine and I own nothing it acts on — no surfaces, no second
harness, no tracker of my own. This is feedback ABOUT THE READER, and it is a
complete result, not a soft no. Say in the reason WHAT I do not own.
NOT WALKED We never got to it.
NOT INTEGRATING and NOT APPLICABLE are DIFFERENT FINDINGS and a maintainer reading a ledger cannot
tell them apart if both are written as "skip". A pattern nobody adopts is a pattern to reconsider; a
pattern nobody can apply is a pattern whose transfer analysis is missing an axis — the second one is
how this ledger got its fourth value (knowledge#6665, 2026-08-23). For a pattern that is NOT
INTEGRATING or NOT APPLICABLE, write "skips all N narrow points" rather than leaving them blank. For
a pattern where research ran, say so. Ask me to confirm or correct it. This is one question.
SECOND, ask the one thing the walk cannot derive — what this wiki's own material did to me:
Where did this wiki leave you?
1. Couldn't find what I needed
2. Found it but didn't understand it
3. Understood it but it didn't work on my substrate
4. It worked, and produced the wrong SHAPE of output
5. It isn't documented at all
6. Other — free text
Option 4 exists because it is the most actionable failure there is and the old form had no box for
it. If I pick it, ask what shape I wanted instead — that follow-up is worth more than the option.
THIRD, ask how much this is costing me: blocker (I can't proceed) · friction (I worked around it) ·
nit (worth mentioning).
FOURTH, ask how to credit this — a name or handle, or "anonymous".
Then DERIVE the remaining frontmatter and SHOW ME what you derived and why, in one short block,
before you write the file. Do not ask me for these; do not invent them either:
- `harness` — from your Step A measurement. If I run several, name the primary one and say in the
body that there are several, because the field takes one value and the truth does not.
- `feedback_type` — `request` if I asked for something built or changed; `capability_gap` if what
I need does not exist; `unclear` if a pattern could not be understood as published; `wrong` if
the research turned up a published claim that is false. Name the basis in one clause.
- `area` — the patterns actually discussed, in my words.
- `desired_output` — one line, in MY words, from what I said during the walk.
If I correct any of them, take the correction.
=============================================================================================
STEP G — THEN WRITE THE FILE
=============================================================================================
Write a file named `feedback.md` in the current directory and tell me its full path. Use exactly
this structure — the headings and the six fields are a contract the page validates before it will
accept the file, so do not rename, reorder or drop any of them:
---
feedback_type: capability_gap | unclear | wrong | request
desired_output: "one line, in my words, of what I want my setup to do"
harness: claude-code | cursor | codex | other | none
area: "the part of the fleet this touches, in my words — not a URL unless I gave one"
severity: blocker | friction | nit
submitted_by: "my name/handle, or anon"
---
## The output I want
<What I want built or changed, in MY voice, drawn from the patterns I chose to INTEGRATE and from
what I said while deciding. If I integrated nothing, say that plainly — a walk that rejects
everything is a complete and useful result. Keep my specifics; do not summarize into generalities.>
## My AI workflow setup
<Your Step A measurements, with the command or path that produced each one. Name every harness if
there is more than one. Say which figures you could not measure and why. This is the section that
tells the maintainers whether a pattern survived contact with foreign substrate.>
## What I tried on the docs
<My answer to the "where did this wiki leave you" question, plus its follow-up. If I named a page,
quote the line that stopped me. If I picked "wrong shape of output", say what shape I wanted.>
## What would have to be true
<My statement of done: what has to be true for the INTEGRATE decisions to be finished. Derived from
the walk and confirmed by me at the ledger step.>
## Anything else
<The decision ledger — one row per pattern, with its decision (INTEGRATE · NOT INTEGRATING · NOT
APPLICABLE · NOT WALKED) and a one-line reason, including the patterns I never reached. Keep NOT
APPLICABLE distinct from NOT INTEGRATING; collapsing them loses the finding. Then any research
findings, with the command or file path that produced each measurement. Then anything I raised that
fits nowhere above. Omit this section entirely if there is genuinely nothing.>
RULES FOR WRITING IT
- Every frontmatter field must be present, and the four fixed-choice fields must use one of the
listed values exactly. `desired_output` and `area` are free text but must be filled in.
- Write what I said. Do not add recommendations of your own, do not propose solutions I didn't ask
for, and do not soften a rejection. If I was blunt, keep it blunt. A rejection with a reason is
the most valuable thing in the file.
- Record a rejection's REASON, not just the rejection. "Not integrating pattern 2 because nothing
on this machine would be left to start work after rejecting pattern 1" is a finding. "No" is not.
- If a research pass fell back to inline measurement because subagent dispatch failed, say so and
say why. That fallback is a documented, expected outcome — hiding it is the only error.
- Do not include anything sensitive: no API keys, no tokens, no internal hostnames of mine, no file
contents from private repos. If I pasted something that looks like a secret, leave it out and tell
me you did.
- Do not pad. A three-pattern walk writes a three-pattern file.
FINALLY
Tell me where the file is and remind me to drop it on the feedback page at
docs.utopiamodels.ai/feedback. That page takes the file and files it on the maintainers' board —
I don't need an account.
Step 2 · Drop the file it wrote
What the file has to contain
- Frontmatter between
---lines, carryingfeedback_type,desired_output,harness,area,severityandsubmitted_by. ## The output I want## My AI workflow setup## What I tried on the docs## What would have to be true## Anything else— optional, omitted entirely when empty