skip to content
Replays

Config Schema Studio

Schema Backed Settings

A persistent config schema grew into writes, resolution, a terminal form, and checked reference docs.

Gantry milestones

3 milestones 16 tasks 33 agents

8 plan 18 execute 23 review

214k peak context

126k median execute

A persistent config schema grew into writes, resolution, a terminal form, and checked reference docs.

6h 28m total 16m 24s per task

7m 34s plan 3h 10m execute 1h 17m review

190 edits 1.3k commands

codex harness

This run turned Gantry's standing preferences from scattered readers and narrow setters into a schema-backed surface that can be loaded, written, resolved, shown, edited, and documented from the same contract. The work was too broad for a single context, so Gantry cut it first into a non-TUI config core, then a config-agnostic modal form foundation, then the settings form and reference layer that joined them.

The build history is useful because it shows where that split had to adapt. Effective resolution in the first milestone was too large until it was replanned around smaller contracts, text editing in the modal foundation needed a retry, and the last documentation pass ended as an already-satisfied gate rather than a fresh code change.

How this walkthrough is structured

Feature

What did the run build and ship?

The tree still exposes a central config schema, schema-aware config loading and writes, source-labeled settings rows, an engine-owned settings write path, a TUI settings modal, and checked config reference material.

Build

How did Gantry structure the work?

Gantry carried the settings overhaul by separating schema mechanics, modal form plumbing, and the final editable surface, with replans clustered around effective resolution and guard coverage.

Milestone 1

Schema Core

8 tasks 29 agents 3h 14m wall time 204k peak context

The config core still stands in `src/engine/config_schema.rs` and `src/engine/global_config.rs`. The schema declares persistent settings, validation sources, defaults or deferrals, environment bindings, and precedence tiers, while the global config module loads, writes, and resolves rows from that metadata. Later code has reorganized some build-module paths, but the central config contract remains present and documented.

This milestone owned the non-TUI configuration engine, which made it the heaviest architectural cut in the run. Its brief asked for one declarative source to cover parsing, validation, writes, effective values, command output, runtime consumers, and guardrails while preserving the old config surface. Review found the original split too broad around effective resolution, so the work was replanned into smaller resolver, runtime, command, and docs pieces before it completed.

Config Schema Contract

1 agents 8m 44s wall time 112k peak context

`CONFIG_SCHEMA` is still the entry point for the persistent settings surface. It carries stable setting ids, key paths, value kinds, defaults, validation sources, environment bindings, writeability, and the harness-selection exception. The same table now feeds documentation and runtime-facing settings rows instead of living as isolated scaffolding.

This sprint gave later workers a contract instead of asking them to infer config shape from old callers. Its boundary was deliberately narrow: define `CONFIG_SCHEMA`, cover the existing file-backed surface, reserve standing preferences that would be made persistent, and refuse ad hoc variables. The run facts show a clean pass, which fits a contract-first piece whose job was to establish names and metadata before behavior moved.

Global Config Load

2 agents 10m 1s wall time 106k peak context

Global config loading now builds a schema value store from the declared settings. The parser looks up settings by schema key path, validates dynamic harness ids through the registry, carries warnings, and keeps compatibility accessors available for callers that have not moved to row-based APIs. Unknown or unrelated file content remains non-fatal.

Once the table existed, this sprint moved global config-file reads onto it while keeping compatibility accessors alive. That was a manageable fresh-agent task because the acceptance line was explicit: parse every shipped path through the schema store and preserve forgiving warnings for malformed or stale input. It completed without recorded recovery.

Generic Config Writer

2 agents 8m 12s wall time 83k peak context

`ConfigWriteRequest` and the schema writer remain in the global config module. Existing narrow config writes are routed through the same prepared request path that validates a schema value, serializes it for its declared key, updates or creates the right section, and avoids partial writes on invalid input. Harness-scoped rows use the same writer shape as ordinary rows.

This piece was the write-side counterpart to schema loading. The brief kept it away from broad UI work and asked for a schema-keyed request that could set or clear file-tier values while preserving comments and unrelated sections. Its clean boundary let the existing narrow commands migrate without multiplying setter paths.

Effective Config Resolution

10 agents 1h 21m wall time 117k peak context 2 replans

`EffectiveConfigSnapshot` still resolves schema entries into typed values with source labels, overridden file values, warnings, and deferral states. Ordinary settings such as effort, timeout, retry, sandbox, and UI preferences pass through a supplied environment lookup rather than direct process reads. The sandbox mode rule that disables a custom command when sandboxing is explicitly off is represented in the resolver path.

Effective resolution was where the first milestone pushed back. The sprint was retried and replanned after review notes showed that combining every source tier, runtime move, and command presentation in one agent context was too much. The revised brief narrowed this worker to ordinary standing preferences and left harness ladders, runtime rewiring, and printing for later sprints.

Assistant Resolution

2 agents 14m 57s wall time 157k peak context

The effective snapshot contains source-aware entries for role harnesses, role model pins, assistant preferences, and per-harness fields. Harness-valued settings draw their valid ids from the registry, role harness selection keeps its no-environment exception, and assistant resolution has its own CLI, project, global, inherited, default, and deferral behavior. Those entries are now visible through the settings catalog and config print path.

This sprint extended the resolver into the settings whose precedence is not ordinary environment-over-file lookup. Its brief was scoped around harness, model, per-harness, and assistant ladders, so a fresh worker could reason about source ordering without touching runtime call sites yet. The run facts record no recovery for this piece.

Runtime Rewiring

2 agents 23m 8s wall time 204k peak context

Runtime configuration now has resolver-backed handoff points in `src/engine/config.rs`, `src/engine/harness/mod.rs`, `src/window_title.rs`, and the TUI animation path. Role-specific effort and timeout values, retry settings, sandbox controls, per-harness configuration, and UI preferences are represented through config objects rather than each consumer reading its own environment spelling. Some build driver files named by the old git facts have since been reorganized, so this sprint's surviving shape is the resolver-backed behavior, not those exact paths.

After the resolver could answer every schema row, this sprint made runtime code consume those answers. The brief was intentionally integration-heavy: config loading, stage budgets, retry policy, sandbox setup, confinement checks, per-harness config, and UI preferences all had to stop bypassing the snapshot. The facts have an incomplete finish record for this row, but the milestone ledger records it as green and the surrounding commits were measured.

Schema Config Command

1 agents 8m 36s wall time 77k peak context

`gantry config` still builds an `EffectiveConfigSnapshot`, turns it into a `SettingsRowCatalog`, and prints rows with effective values, source labels, help text, environment keys, override notes, defaults, and deferrals. The command keeps narrow write forms for harness and model compatibility, but the broad readout comes from the catalog instead of a parallel hand-built summary.

This sprint moved the repo-free config command onto the effective resolver after runtime consumption was in place. Its job was presentation and compatibility: print every schema-declared preference with source information while preserving the existing narrow edit syntax. It completed without a recorded recovery.

Docs And Guardrails

5 agents 27m 21s wall time 143k peak context 1 replan

`docs/agents/config.md` now includes a schema-declared settings reference that names accepted values, defaults or deferrals, precedence, and environment bindings. Refused variables are documented as outside persistent config scope, while production guards and focused tests keep parsing, writing, resolving, printing, documentation, and form metadata from drifting back toward per-setting tables. The later final milestone added more settings-row coverage on top of this base.

The final core sprint was rerun after review identified holes in the guard strategy. Its revised brief asked for documentation to follow the schema and for source-level tests to reject new key-name or harness-id dispatch outside narrow compatibility adapters. That recovery made the milestone's promise executable instead of relying on convention.

Milestone 2

Modal Form Foundation

4 tasks 14 agents 1h 20m wall time 155k peak context

The modal foundation is still split between the vendored `mcurses-menu` crate and Gantry's own `src/tui/modal.rs` and `src/tui/input.rs`. The vendor snapshot exposes modal form layout, focus, selectors, checkboxes, and text-input key claiming, while Gantry keeps reusable text editing and caller-owned form descriptions on its side. The root test script also includes an explicit vendored crate check.

This milestone stayed deliberately config-agnostic. Its brief treated the upstream modal crate as the owner of generic widget mechanics and Gantry as the owner of values, mutations, caret state, and later schema knowledge. Only the text-editing sprint needed a retry; the rest of the modal foundation stayed inside the planned boundary.

Vendor Boundary Refresh

2 agents 22m 16s wall time 155k peak context

`vendor/mcurses-menu` remains a checked-in snapshot with its own `VENDORED.md`, examples, tests, and modal layout code. The root `bin/test` path still runs the vendored crate through a manifest-targeted command, which makes the snapshot a tested input to Gantry without changing workspace membership. The vendor side contains generic modal mechanics, not settings-specific behavior.

This sprint refreshed the vendored modal crate before any Gantry form state depended on it. The brief was mostly about process discipline: reconcile upstream drift, update lock data, document the snapshot relationship, and make the root gate exercise vendor tests without making the vendor a workspace member. It completed cleanly.

Unified Text Editing

4 agents 18m 6s wall time 112k peak context

`TextInput` still owns single-line editing, caret movement, deletion, and paste normalization in `src/tui/input.rs`. The modal boundary imports the vendored text-input key predicate so key claiming and value mutation no longer drift independently. Existing prompt modals and the later settings form use the same editing primitive.

This was the modal milestone's stressed piece. The worker had to close key-routing divergence between Gantry and the vendored modal crate while adding paste behavior to Gantry-owned text state, and the run facts show a retry after review. Keeping the task independent of settings meant the repair could focus on terminal editing semantics.

Description Contract

2 agents 12m wall time 99k peak context

`ModalFormDescription` and its row types remain in `src/tui/modal.rs`. They can describe text inputs, selectors, checkboxes, sections, and help rows in declaration order, carrying labels, selected state, help, validation text, and opaque field ids. The types do not know about config keys or persistence.

With editing behavior unified, this sprint defined what a form looks like without deciding what any setting means. The brief asked for render data only: inputs, selectors, checkboxes, sections, help text, actions, and stable caller-owned identities. That boundary was small enough to pass without recovery.

Session Foundation

2 agents 17m 34s wall time 144k peak context

The modal session code can open, navigate, edit, cancel, and submit multi-field forms while preserving caller field identities across redraws. Text inputs, selectors, and checkboxes round-trip through Gantry state, and section or help rows stay non-editable. The settings modal later consumes this foundation rather than creating a separate modal path.

The last modal-foundation sprint made the form description interactive while keeping schema and persistence out of scope. Its contract put editable values, caret positions, toggles, selection, validation display, submit, and cancel outcomes in Gantry-owned state. It completed cleanly, leaving the settings milestone with a usable form session instead of another rendering contract to invent.

Milestone 3

Settings Docs Form

4 tasks 10 agents 1h 12m wall time 214k peak context

The final settings surface still exists through `SettingsRowCatalog`, engine-owned write results, TUI state integration, and the schema-backed config reference. Users get source-labeled rows, editable file-tier values, override notes, validation messages, and generated or checked documentation from the same row model. Some final-run work is now inseparable from later edits, but the catalog-to-form-to-docs architecture remains visible.

The final milestone connected the schema core and modal foundation into a user-facing settings surface. Its brief explicitly warned that earlier schema work was as-built rather than complete, so the first sprint had to close display-visible resolver gaps before writes, UI, and docs leaned on it. The top ledger records the milestone as green with a plan-impact note, which means the shipped result met the gate while some source-plan ambitions needed later attention.

Settings Row Contract

2 agents 15m 13s wall time 126k peak context

`SettingsRowCatalog` remains the shared row boundary in `src/engine/global_config.rs`. It expands schema settings, including harness-scoped rows, into display and edit metadata for commands, docs, and the TUI. The catalog carries effective values, source labels, file-tier values, warnings, override notes, environment keys, help text, value kinds, options, and writeability.

This sprint built the read model that every user-facing settings surface would consume. It had to turn schema and effective-resolution entries into ordered rows with labels, grouping, editable value kind, source, file-tier value, warnings, override notes, and documentation metadata. The brief also assigned it the remaining blank-value forgiveness gap from the earlier core.

Engine Settings Writes

1 agents 18m 15s wall time 122k peak context

`SettingsWriteRequest` and `SettingsWriteResult` still wrap the generic config writer with a refreshed catalog response. A successful write returns messages, warnings, override notes, and enough row identity for the UI to preserve focus; a failed write reports validation or persistence errors without treating a local draft as effective. The path supports ordinary and harness-scoped editable rows.

This sprint added the write-and-echo contract the form needed. The brief kept edits engine-owned: a front end could request a schema row change, but it had to wait for persistence, reload, and effective resolution before displaying the result as truth. It completed without recorded recovery.

TUI Settings Form

2 agents 27m 26s wall time 214k peak context

The TUI state still exposes an editable settings modal backed by `SettingsRowCatalog`. Rows become text inputs, selectors, or checkboxes according to their schema value kind, and save dispatches a single engine-owned write request before refreshing from the returned catalog. Validation failures keep the draft visible while successful echoes update the modal and run metadata.

This sprint joined the settings row catalog to the modal session. Its brief asked for menu reachability, schema row coverage, widget mapping, dynamic enum options, engine write requests, validation display, focus preservation, and no local effective-value mutation before the engine echo. The run facts show a clean build for this connection point.

Generated Config Reference

1 agents 3m 17s wall time 85k peak context

The config documentation and command output still follow the schema-backed row model. The reference covers standing preferences, accepted values, defaults or deferrals, precedence, dynamic harness options, editability, and refused variables, while tests guard against missing rows in docs, print output, and form metadata. The final proof is partly absorbed into the current global config tests rather than visible as a separate user-facing feature.

The last sprint was a hardening pass rather than another broad feature build. Its brief tied broad config output and reference documentation to the settings row contract and asked for a one-row proof that future settings travel through the whole chain without bespoke production code. The facts record a gate note and no commit sha, matching the ledger's already-satisfied result.