Config File
One page in the native app, under This machine, that manages qcontrol's `config.yaml` in three modes: edit it here (in an editor, from a library of starters), governed by the company's plane, or fetched once from a published file. An agent drafts the file over the app's MCP server from the person's plain instructions. The draft is checked by qcontrol and applied by the person.
Report[the mock](/pages/native/config): the Config page in the native skinexecutive summary, decisions, the audit →New in this cycle: The Config page in the native skin, under This machine (c146 R3): three modes on Policy Config's Config File vocabulary
Why
People will change what the sensor watches, where its events go and what it enforces, and many will ask their agent to do it. The configuration has three possible homes: this machine, the company's plane, or a published file. The page has to say which one holds it, and let each lead somewhere honest. A blank editor is a poor start, so manual mode starts from a library of starters: what most people need, then a variant per role. When an agent drafts a change, a mistake can't reach the sensor. So the agent gets qcontrol's own check, errors it can act on, and a draft the person reads and applies.
Objective
Done means:
- The page: three modes, every state drawn in the native skin and built in the app on Policy Config's Config File vocabulary, with as-written and effective views, an editor (gpui-component's, nothing custom), and the agent's draft with Apply or Discard.
- The starters: Recommended, Developer laptop and Data/analyst laptop, each checked, in one library hosted by Qpoint.
- The contract: a reference generated from qconfig, checked examples, an intents catalog, and errors written for an agent.
- The tools:
config-state,config-read,config-reference,config-starters,config-check,config-proposeon the app's MCP server. There is no write tool. - The eval: for every instruction in the intents catalog, the first proposal checks clean and the page shows it ready to Apply.
Scope
- Cycle docs:
cycles/c146.config-file/ - Design site:
app/pages/pages/native/config.vue, the sketch, the story, a shot program - Sister projects:
../qnativec10 (the page, the editor, the tools, Guide 05).../qcontrolis read onmainand never changed; engineering gets asks. - Out: following an address over time (R1), overlays (c148), the plane's credential exchange, authoring on the web, and a custom editor
Key Changes
- stage 1 (2026-11-13): the prompt was saved verbatim and the plan written from c138's outline, Guide 05, qconfig on
main, the app's MCP server and c145's plan. Nine calls were set out with defaults:- point or fetch once
- the words ("policy" collides)
- a V1 page rather than a Dev page
- a direct, guarded write rather than a draft
- the app's own server
- qconfig linked by git
- where an agent's change lands
- the editor spike
- refusal when the plane manages the file
- the walk (2026-11-13): Mark ruled the calls:
- R1: fetch once, with Check for changes.
- R2: the names and the first pass come from c121's Policy Config › Config File (
/pages/phase4/mock/policy-config/config-file). "Policy file" was a slip, and the file isconfig.yaml. - R3: a V1 page under This machine.
- R4: the agent drafts and the person applies.
- R5: the app's own MCP server.
- R6: validation is asked of qcontrol.
- R7: the draft is the whole file.
- R8: the editors that exist (gpui-component's
Editoranddiff), nothing custom. - Starters: Recommended plus per-role variants, in one Qpoint-hosted library, with more possible online.
- C9 goes to Mark Peterson. Its overlay idea (stricter local layers, agents on personal accounts kept out of company directories) opened c148 Config Overlays, stage 1.
- kick-off (2026-11-13): Mark: "Kick off, build mock." Phase 2 went first. Phase 1's starters were written with it, because the mock needs them.
- Phase 2, the mock (2026-11-13, uncommitted):
/pages/native/config(app/pages/pages/native/config.vue), registered as Native — Config (phasenative, collapsec146-config).- This machine's file is the world's own, from the bridge's
/api/config.freshhas no file, so it draws the stock-document state. - Fixtures in
app/data/config-c146.ts:- the three starters (Recommended, Developer laptop, Data or analyst laptop), at a fixture library address,
qpoint.io/configs; - Claude Code's draft;
- HQ's file (Meridian, v13);
- the fetched files: one good, one invalid, one newer.
Every file is written to qconfig's schema onmain. - the three starters (Recommended, Developer laptop, Data or analyst laptop), at a fixture library address,
- The check stands in for qcontrol's (R6). It applies the strict schema: unknown keys, required fields, and targets that name undefined behaviors. Each problem gets its line, its key path and the nearest valid key ("did you mean
plugins?"). Theit_contactkey in the pilot world, proposed by c137 but not in qconfig yet, shows as a warning, not an error. All fixtures pass, and the invalid one fails on the right line. - Edit here:
- the editor sits in the layer's
UxEditorFrame, with the starters in its tray and Written and Effective tabs; - the gutter marks error lines;
- Apply and Discard edits;
- versions with Restore;
- an agent's draft as a folded diff, with Apply and Discard (R4, R7);
- Applied as v3, with Revert.
- the editor sits in the layer's
- Managed by your company:
- not connected (an address and a token);
- signing in;
- connected and read-only, saying who manages it, with the other modes locked;
- an agent refused (C9's first pass);
- refused;
- not answering.
- From a published file:
- an address, or a file from the library;
- fetching;
- shown, with its hash;
- invalid, with nothing written;
- written, with the record of origin at the top;
- Check for changes, with the difference (R1).
- Other changes: the rail gains Config under This machine, but only where a mock links it, so earlier captures keep their rail (
NativeWindow). There are four new glyphs inNativeIcon. - Captures: sixteen,
c146-config-*(programscripts/shot-programs/c146-config.json, threadc146-config, subjectpage/native-config), each window as tall as its page. - The checker imports
yaml. It's innode_modulesas a transitive dependency, not inpackage.json. To add when this is committed.
- This machine's file is the world's own, from the bridge's
- Review stop 1 (2026-11-13), six questions:
- The mode labels: Edit here · Managed by your company · From a published file. Do these read as Policy Config's vocabulary? HQ's file is labelled "Policy Config v13".
- A published file replaces
config.yamlwhole, keeping the old file as a version, in line with R7. Guide 05 had it land as aconf.d/include, but includes can't carry sinks or UI. Agree? - The starters live in the editor's tray. Or should they be a first step of their own when there's no file?
- Versions on the endpoint carry Policy Config's History over. Keep them, or is Revert to the last version enough?
- Ask your agent sits on the page, with three example instructions. Keep it here, or only on Help?
- Tyler's question, made visible by the HQ state: does the company's Policy Config reach this machine as this
config.yaml?
- Review stop 1 walked (2026-11-13): Mark took every recommendation.
- Q1: the labels stay as drawn: Edit here · Managed by your company · From a published file.
- Q2: a published file replaces
config.yamlwhole, with its origin at the top; the old file is kept as a version. This supersedes Guide 05'sconf.d/landing. - Q3: the starters stay in the editor's tray. When there's no file, the page also opens on a Pick a starter step: three cards, each saying who it's for and what it does, or an empty file. Built, and
c146-config-no-filerecaptured. - Q4: the endpoint keeps the versions list, with Restore on each. It also records what agents changed.
- Q5: Ask your agent stays on Config, and Help › Getting started gets the connect line. That lands with Phase 3 and 4's native build.
- Q6: the "Policy Config v13" label on HQ's file is marked an assumption on the mock page. Tyler is asked: does the plane deliver the company's Policy Config to the sensor as
config.yaml, or alongside it?
- Phases 3–4, the app (2026-11-13, qnative c11, branch
c11/config,73316aa): built in its own worktree (.claude/worktrees/c11-config), because another session was working in qnative's guide.- The page:
Route::Configunder This machine, andpages/config.rswith every state the mock draws. The editor is gpui-component's code editor (YAML, line numbers, each problem marked on its line) in QGUIkit'sEditorFrame(R8, nothing custom). - The check (R6's stand-in): qconfig's own parser (serde-saphyr 1.3), with structs mirroring qconfig's schema on qcontrol
main. Each problem gives its line, its key path and the nearest valid key. - Six guide tools:
config-state,-read,-reference,-starters,-checkand-propose. There's no write tool (R4).config-proposerefuses an invalid document with its problems, and refuses on a managed machine (C9's first pass). - Tests: an agent proposing through
guide::callis tested end to end: the invalid document refused with "did you meanplugins", the valid one shown for the person, and nothing applied. The whole workspace passes. - Captures: five native captures mirrored here as thread
c146-config-native(programscripts/shot-programs/c146-config-native.json), B beside A. - Open: writes stay in the app until Kamal answers who may write
config.yaml. The editor shows YAML without colours (the tree-sitter feature, to look at). Fetching any address waits for the docs site's library.
- The page:
- Harness ids corrected (2026-11-13): the starters and HQ's file named
claude-code,cursorandcodex. qcontrol's rules useclaude-cli,cursor-cliandcodex-cli(qconfig's tests, the monitor's inventory tests), so they are fixed in the lab fixtures and the app. The 16 lab captures were retaken. - Merged (2026-11-13): Mark: "Merge it now."
c11/configmerged into qnative main as313bd7c, after c10's guide walk (8382135) and c9 and c12's records (049e481) landed. The only conflict was the cycles index. app and stories tests pass on the merged tree (25 and 86), and main type-checks. The worktree and branch are removed. Not pushed. - Phase 1, the intents catalog (2026-11-13):
intents.mdhas twelve plain instructions, each with the fragment that answers it, written againstmeridian-day90's file. The instructions cover a sink, a file log, a secret kept out of the file, OpenShell for Cursor, filtered events, the tray, stop watching a harness, a starter, "what is it doing?", and a refusal explained. Each fragment, merged into the whole file, passes both the app'sconfig-checkand qconfig's own loader on qcontrolmain(8677b44ed, run from a scratch example). The harness ids are qcontrol's. - Phase 5, the eval (2026-11-13):
eval.md, with every run's tool calls and drafts ineval/.- The setup:
- qnative main
313bd7c, built from a scratch worktree; - synthetic data, world
meridian-day90, guide port 7895, a fresh app per instruction; - headless Claude Code on Opus 5.5 with only the guide's MCP server.
- qnative main
- On the plan's words, 9 of 12 pass. Every proposal the agent made checked clean the first time (8 of 8), and every draft also passes qconfig.
- The three misses:
- #6 ("turn the tray off") and #8 ("stop watching Aider") were routed to find-in-app and never reached the config tools.
- #5 wrote
Bearer $__local{KEY}. Both checkers pass it, but qsecrets resolves only a string that is exactly the reference.
- The fixes, tested on a scratch build: three one-line wording fixes (F2 secret references, F3 routing at the top of the guide's instructions, F4
behaviors: []) make all three pass. They are not applied to qnative; the patch iseval/fixes-F2-F4.patch. - F1, the bigger finding: the stand-in check passes 12 of 15 documents qconfig refuses, and refuses 2 it accepts. Linking qconfig is recommended.
- The setup:
- Phase 0, owed and done (2026-11-13):
- The sketch is One file, three sources, one check (
app/pages/cycles/design/sketches/c146-config.vue). It is registered inprogram-sketches.ts, captured asc146-sketch-configbyc130-sketches-design.json, and placed under § The shape. - The story is
app/data/stories/c146.ts, wired incycle-stories-mock.ts. It has twelve decisions (R1–R8, Q2–Q5) and five outcomes, with the sketch as hero.
- The sketch is One file, three sources, one check (
- Review stop 2 (2026-11-13), three calls:
- Land F2–F4 in qnative?
- F1: link qconfig as the stand-in check, or fill the mirror's gaps?
- Mark's walk of the twelve instructions, with a managed-machine instruction left for it while C9 is open.
- The walk, begun (2026-11-13, in the c146 session): Mark: "let's walk them here."
- The setup: the merged build (
313bd7c) and a scratch build with the wording fixes, swapped in one window on guide port 7895. Mark's own app on 7891 predates the merge and has no Config page. Each instruction gets a fresh Claude Code with only the guide. - #5: failed on the merged build (
Bearer $__local{…}), passed on the fixed one. The agent also explains where the prefix goes. - #6: failed on the merged build (Messages › Settings), passed on the fixed one.
- F6 ruled:
- W1:
ui.trayis the one menu-bar icon, whoever draws it; an ask to engineering. - W2: the agent drafts
ui.tray: falseand names Messages' switch. This works only fromconfig-reference'sui.traytext, not from an instruction line. - W3: "tray" means the menu-bar icon only, and the guide's
messages.trayis retitled "Show messages in the tray".
- W1:
- F7 found: point at Apply via
config.draft. - #8:
- On the merged build, the agent reached config this time. Its first proposal was refused: F8, a rule's
--comment written as a YAML line. It also matched by binary, because a section's reference has no harness ids (F9). - On the fixed build it passed with
harness.id == "aider"andbehaviors: [], and pointed at Apply (F7 works). - With F8 and F9 added, it took one reference call.
- On the merged build, the agent reached config this time. Its first proposal was refused: F8, a rule's
- The fixes: in
eval/fixes-F2-F9.patch(eight wording lines and one region title), not applied to qnative. All three misses pass on that build.
- The setup: the merged build (
- The fixes landed (2026-11-13): Mark: "Yes, land it."
9daa5f8on qnative main (not pushed) carries F2, F3, F4, F6's W2, F7, F8 and F9 intools.rsandmcp.rs.cargo test --workspacepasses.- It was committed through a temporary index, because qnative c13 holds staged work in the same tree.
- Handed to c13:
- W3, the retitle of the tray region, which moves in c13 to
safety-settings.tray; - W2's sentence, which names Messages › Settings and should name the new place.
- W3, the retitle of the tray region, which moves in c13 to
- Phase 6, the record (2026-11-13):
- Guide 05 (
../qnative/cycles/c3.developer-mode/guide/05-config.md) rewritten from a proposal into the contract: the three modes and their labels (Q1), a published file replacingconfig.yamlwhole and fetched once (R1, Q2), the six tools and what they return, the agent drafting and the person applying (R4, R7), the check and its error shape with F1's drift, and the asks still open, W1 included. qnative8cbd367, committed alone through a temporary index (c13's staged work left as it was), not pushed. - c145's configure step (Set up this machine, step 3) points at the Config page:
/pages/native/configandRoute::Config. - The Outcome below.
- Guide 05 (
Outcome
Written 2026-11-13, with the cycle still open: C9 and Q6 wait on others, so it is not closed or archived.
What was built
- The mock (medium A):
/pages/native/configin the native skin, every state of the three modes (Edit here · Managed by your company · From a published file), on Policy Config's Config File vocabulary (R2). Starters beside the editor and a Pick a starter step when there's no file (Q3), versions with Restore (Q4), an agent's draft as a folded difference with Apply or Discard (R4, R7), and Ask your agent (Q5). Sixteen captures,c146-config-*. - The native page (medium B, qnative c11):
Route::Configunder This machine (R3), on gpui-component's editor inside QGUIkit'sEditorFrame(R8), every state the mock draws, a story and a region-text test per state. Five native captures,c146-native-app-config-*, beside the lab's. - The contract: the reference read from qconfig's schema on
main, three checked starters (Recommended, Developer laptop, Data or analyst laptop) at a fixture library address, errors written for an agent (line, key path, message, nearest valid key), and the twelve-instruction intents catalog (intents.md), each fragment loaded by both the app's check and qconfig itself. - Six guide tools on the app's own MCP server (R5):
config-state,config-read,config-reference,config-starters,config-check,config-propose. None writes: Apply, Discard and Restore are the person's buttons. - The record: the sketch (One file, three sources, one check), the story (
app/data/stories/c146.ts), and Guide 05 as the contract.
What the eval found
(eval.md, headless Claude Code on Opus 5.5 with only the guide, world meridian-day90, n = 1 per instruction, 20 runs, $3.76.)
- On the plan's words and the merged build, 9 of 12 passed. Every proposal the agent made checked clean the first time (8 of 8 that drafted; #11 was refused, as it should be), and all thirteen clean drafts across the eval and its reruns also load in qconfig.
- The three misses were two routings (the tray and Aider went to find-in-app) and one draft both checkers passed but that was wrong (
Bearer $__local{…}, which qsecrets sends as literal text). - With the wording fixes, all three passed (5f, 6g, 8g), and the walk confirmed it: each miss fails or wobbles on the merged build and passes on the F2–F9 build. The walk added F6 (which tray; ruled W1–W3), F7 (point at Apply by
config.draft), F8 (a rule's--comment on a YAML line) and F9 (harness ids in a section's reference). - F1: the stand-in check passes 12 of 15 documents qconfig refuses and refuses 2 it accepts. None of the eval's drafts hit a gap, but "an invalid draft never reaches the person" holds only as far as the mirror goes.
What landed (qnative main, none pushed)
313bd7c: c11 merged, the page, the check and the six tools (Mark: "Merge it now").9daa5f8: the eval's and the walk's wording: F2, F3, F4, F6's W2, F7, F8, F9 (Mark: "Yes, land it");cargo test --workspacepasses, 369 tests.8cbd367: Guide 05, the contract.
What stays open
- C9, for Mark Peterson: on a managed machine, may the agent explain a change instead of drafting it? Until then the proposal is refused with "Managed by your company. Changes are made there."
- Q6, for Tyler: does the company's Policy Config reach the sensor as this
config.yaml? HQ's "Policy Config v13" label is an assumption until he answers (and c145 asks what in the file says a plane is expected). - F1: link qconfig into the app as the check (recommended), or fill the mirror's gaps. A qnative cycle of its own, not ruled yet.
- Engineering's asks (plan.md § Asks): a check entry point with paths and lines (R6); who may write
config.yamlwhile the monitor runs elevated (until then Apply writes to the app's record only); whether a changed file is picked up without a restart; and W1, thatui.traygoverns the one menu-bar icon and qtray never runs beside the app. - Handed to qnative c13: W3 (the tray region's full title, as
safety-settings.tray) and W2's sentence, which should name the switch's new place. - Smaller: fetching any https address waits for the docs site to host the starter library; the real fetch hashes with SHA-256 (a stand-in digest today); YAML colours in the native editor (the tree-sitter feature); Config's map entry could carry the words people use ("watch", "audit", "collector") so find-in-app agrees (F3's second half).
The shape

The sketch (Phase 0, drawn 2026-11-13 at review stop 2).
- The problem. One strict file (
deny_unknown_fieldseverywhere) has three possible homes, and a mistake in it reaches the sensor. People will ask their agents to change it, and an agent guessing at a strict schema fails in ways the person can't read. - The core idea. One file, one check, one record of changes, shared by the page and the agent. The page says which source holds the file. The agent gets the reference, the starters and qcontrol's own errors so its first draft can be right. It proposes the whole file (R7), and only the person applies it (R4).
- The pieces:
- three sources: Edit here, Managed by your company, From a published file (Q1);
config.yaml, as written and as it takes effect, with versions;- one check, asked of qcontrol (R6), with the app's stand-in until then;
- six tools on the app's MCP server (R5), none of which writes;
- the person's Apply, Discard and Restore.
- The pattern. Read, learn, check, propose, apply. The agent points and never presses, the same rule as the guide's tours (c145) and Simulation mode (c144).
- What stays open:
- C9, for Mark Peterson: on a managed machine, may the agent explain a change instead of drafting it?
- Q6, for Tyler: does Policy Config reach the sensor as this file?
- engineering's three asks: the check, the write, and the reload.
- the stand-in check's drift from qconfig, found by the eval (
eval.mdF1).
Visual record
23 captures — heroes, page slices, and full-page renders. Click to view.
Sketches — the structures, drawn in the design system
2026-11-10· 2 captureslatest

Phases 3–4 · the Config page in the real app, mirrored from qnative c11 (B beside A)
2026-11-13· 5 captures




Phase 2 · the Config page in the native skin, three modes, every state
2026-11-13· 16 captures














