Repository-scoped · content-hashed · terminal-native
The sun travels. The shadow sweeps the hours. The gnomon does not move — and that is precisely why the dial can be read. Remove the blade and you have decorated stone, not an instrument.
This harness names itself after that object. .gnomon/ is the fixed configuration — models, roles, tools, approval — content-hashed and committed with your repository. Everything else is shadow.
cd my-project && gnomon launch
Working, pre-1.0 · 400+ tests · CI green
Fig. 0 — Plan view (looking down). Fixed gnomon; black umbra projected from the blade.
Why this name. Behaviour is readable because something holds still. The harness puts that something in a directory you commit.
Performance — measured, preliminary
Preliminary · terminal-bench-core==0.1.1 · small n · not a leaderboard · full measurements §7
Ask most coding agents why did you do that and there is no answer. Configuration scatters across dotfiles and machine state — the same repo behaves differently for two people.
The model varies. The conversation wanders. The tools differ each run. .gnomon/ does not.
The real path, in order. Slash commands stay local. Everything else: role → skills → context → tools under approval policy.
Three guarantees in this path:
bash gated.result · refusal · apparatus_failureFig. 1 — Agent turn loop. Slash commands stay local; everything else routes through role, approval, and honest outcome buckets.
write — absence, not instruction.Rust owns verifiable parts. TypeScript owns the loop. Sessions and audit live outside the hashed surface — logs inside .gnomon/ would change the hash every turn.
Fig. 2 — Rust owns verifiable surface, edit, and exec. TypeScript owns the loop. Sessions and audit sit outside the hash.
The blade is .gnomon/: fixed, identifiable, content-addressed. Replies, tool traffic, session history — the shadow.
Rust and TypeScript compute the same surface hash; a test holds them together. conformance/ pins exit codes, enumerations, manifest shape.
Workflows where repository-scoped behaviour matters — not generic productivity claims.
Ollama on laptop; same agent on CI.
Surface committed. Clone anywhere — same roles, tools, gate.
Review agent behaviour in PRs.
bash_allow changes in diff. Hash updates on merge.
What was permitted? Who approved?
Hash-chained JSONL + surface_hash. audit verify.
Pipeline via gnomon task --json.
Published exit codes. Bucket from exit value.
Survey before writes.
Verifier first. Skills proposed. Implementor last.
Roles separated by capability.
Coordinator can't edit. Verifier can't write.
| Role | Cannot |
|---|---|
coordinator | edit; outside write_allow |
implementor | — (sandbox reach) |
verifier | write, edit |
.gnomon/.External benchmark · terminal-bench-core==0.1.1 · 8 hard P0 tasks · same container and verifier · valid-pass % = passes ÷ (trials − apparatus failures).
| Model | gnomon | gnomon +P0 | goose | opencode |
|---|---|---|---|---|
| DeepSeek V4 Flash | 39% | 36% | 43% | 19% |
| GLM 5.3 Flash | 38% | 55% | 57% | 27% |
Parity with goose (not significant at this n). ~2× pass rate vs opencode. Wins the one discordant task (configure-git-webserver 6/6 vs goose 0/1). Solo run on 30-task subset (gpt-5.3-codex): 15/30 (50%), ±18pp — no comparator on that arm.
Five harnesses, four model tiers, deterministic scoring. Author conflict stated; still useful for context cost. ~1.1k-token system prompt vs 7–16k for opencode.
| Tier | gnomon | opencode | pi | omp |
|---|---|---|---|---|
| qwen3.6-35b · tok / task | 4.3k | 55k | 7.2k | 74k |
| gpt-5.3-codex · tok / task | 4.6k | 76k | 2.3k | 30k |
| vs opencode (completed tasks) | 13–43× leaner · drift-confirmed Aug 2026 | |||
Criteria met (% of scored checks). Frontier tiers saturate — three of five harnesses hit 100% — so external tasks discriminate where the smoke test cannot.
| Tier | gnomon | opencode | pi | omp |
|---|---|---|---|---|
| qwen2.5-7b | 89% | 31% | 62% | 76% |
| qwen3.6-35b | 100% | 71% | 89% | 96% |
| gpt-5.3-codex | 100% | 57% | 100% | 100% |
| Same model: internal → TB30 | 100% → 50% — saturation demonstrated | |||
Benchmark found a real bug: "Ask before writing" in system.md caused frontier models to propose edits instead of calling tools (86% → 100% after fix).
Three-bucket model (result / refusal / apparatus_failure) applied to benchmark scoring. Six apparatus defects found and fixed across the Aug campaign.
| Fix / property | Effect |
|---|---|
settle() (commit 0087d00) | Apparatus-failure rate on +P0 arms: 38.5% → 14% |
| Valid-trial scoring | Crashes excluded from denominator; crash count printed per cell |
| Identical adapter clocks | Prior 600s cap had penalised gnomon’s slow successes |
| Conformance fixtures | 4 golden manifests · 400+ tests · README tested against code |
Speed axes only — harness overhead and local generation. Distinct from token efficiency (II) and capability pass rates (I).
| Measurement | Result |
|---|---|
| Audit trail on vs off | 338ms vs 354ms — within noise |
| Startup (tsx boot vs gnomon logic) | ~197ms vs ~33ms |
grep vs bash (same task) | 1 call / 4.5s vs 11 calls / 25.1s |
| Local inference · DFlash speculative decoding | ~1.3–1.5× wall-clock · output-exact |
Local inference: DFlash speculative decoding is a free ~1.3–1.5× wall-clock speedup on generation-heavy work; output-exact so quality is unchanged (36/36 tasks pass identically on and off). Does not move token counts (II) or Terminal-Bench numbers (I — those ran on cloud models). Timeout headroom on long local tasks is plausible (p90 at 77% of the cap) but not shown here — this run’s tasks were all <26s. Not run against SWE-bench Verified. Prior Aug 27 hosted sweeps (goose / forge / gnomon / opencode) are directional only — apparatus defects depressed some arms.
A harness that hides its gaps is worse than one that has them.
gh, az…), and the web. It doesn't run itself as a background job on someone else's server: no queue, no worktree pool. One unattended path: cron-scheduled loops — ticks on the scheduler.webfetch (SSRF guards). bash still reaches the network.Primarily tested on bash · available on Windows through WSL2 · WSL may still have bugs.