Skip to content

docs: add a closed-loop overview to the README - #10

Merged
undeemed merged 6 commits into
mainfrom
fm/fpsm-readme-8k
Jul 28, 2026
Merged

docs: add a closed-loop overview to the README#10
undeemed merged 6 commits into
mainfrom
fm/fpsm-readme-8k

Conversation

@undeemed

Copy link
Copy Markdown
Owner

Intent

Captain order (2026-07-25): update the fpsmaxxing README so a reader landing on it instantly grasps that fpsmaxxing is a closed feedback loop that fine-tunes system + hardware performance. Docs-only change to README.md. Near the top (right after the title/intro blurb and the alpha IMPORTANT note, before deep architecture detail) I added a new '## The closed loop' section containing: (1) a GitHub-native Mermaid flowchart showing the full loop end to end as a cycle - Measure (FPS, latency, frametimes, thermals) -> Policy engine (bounded adjustment) -> Broker (apply via typed capability, snapshot + TTL lease) -> Watchdog (revert on regression or safety violation) -> Evaluator (keep or roll back) -> iterate back to Measure; and (2) a short five-sentence prose walkthrough naming the pieces: unprivileged gateway (typed MCP tools, no shell/admin/raw device access), capability registry + policy engine, privileged broker, provider sidecars, durable experiment journal, independent watchdog, deterministic evaluator. Deliberate decisions/tradeoffs a diff reviewer would not know: no ASCII fallback for the Mermaid block is intentional since GitHub renders Mermaid natively; the existing linear '## Architecture' ASCII diagram and the 'observe -> propose ...' text loop were intentionally left in place (different views, not rewritten) per the instruction to not touch unrelated sections; every claim is grounded strictly in README.md, docs/ARCHITECTURE.md, and docs/IMPLEMENTATION_PLAN.md with no invented components or promised features; safety invariants (LLM never gets admin/shell, every write has snapshot+TTL+rollback, watchdog independent) are kept visible in the prose as the selling point; each full sentence is on its own line per repo/docs Markdown convention; and no co-author trailer was added to the commit per the project's global instruction. No code or schemas were touched, so fmt/clippy/test/schema checks are unaffected.

What Changed

  • Added a ## The closed loop section near the top of README.md, right after the alpha notice: a GitHub-native Mermaid flowchart (Measure -> Policy engine -> Broker -> Evaluator, with the watchdog drawn out-of-band as a dashed lease/TTL-or-safety revert edge into the broker) plus a short prose walkthrough naming the gateway, capability registry and policy engine, broker, provider sidecars, experiment journal, watchdog, and evaluator. Claims about unimplemented stages are hedged as design intent to match the existing status list and FAQ.
  • Redrew the watchdog arrows in the existing ## Architecture ASCII diagram so the watchdog reverts through the privileged broker instead of pointing at the telemetry normalizer, keeping it consistent with the new Mermaid diagram.
  • Synced the docs: docs/ARCHITECTURE.md now states the watchdog reverts to the pre-state snapshot through the broker on lease expiry or safety violation, and docs/README.md points readers to the README's closed-loop overview before the detailed design.

Docs-only; no code, schemas, or tests touched. The Test stage rendered the README through a GFM + Mermaid 11.12 pipeline, asserted the diagram's edges and a clean parse, and ran cargo test --workspace --locked green.

Risk Assessment

✅ Low: Docs-only addition of 25 lines to README.md with no code, schema, or build impact; every claim is hedged and traceable to ARCHITECTURE.md/IMPLEMENTATION_PLAN.md, and the diagram now matches the watchdog-independence invariant after three converged fix rounds.

Testing

Rendered README.md at the base and target commits in headless Chromium through a GitHub-equivalent Markdown+Mermaid pipeline and captured before/after landing screenshots, a full-page render, and a 2x close-up of the new closed-loop diagram; the diagram renders with no Mermaid syntax errors and its SVG edge ids confirm the cycle closes (Measure->Policy->Broker->Evaluator->Measure) with Evaluator->Broker rollback and Watchdog->Broker revert, while the full-page shot shows the pre-existing Architecture ASCII diagram and text loop untouched. Cross-checked every component named in the new prose against README.md, docs/ARCHITECTURE.md, and docs/IMPLEMENTATION_PLAN.md. cargo test --workspace --locked initially failed on the sandbox's C toolchain (zig cc rejecting the Rust target triple, no ar), which I fixed with local compiler shims; the full suite then passed, and the target/ build output was removed so the worktree is clean.

  • Evidence: README landing view AFTER - new "The closed loop" section with rendered Mermaid cycle (local file: /tmp/no-mistakes-evidence/01KYH47XZ1DDQ3TXT7C6ZJHZMS/01-readme-landing-AFTER.png)
  • Evidence: README landing view BEFORE (base 7f3ab1d) - alert goes straight into "Why FPSMaxxing?" (local file: /tmp/no-mistakes-evidence/01KYH47XZ1DDQ3TXT7C6ZJHZMS/00-readme-landing-BEFORE.png)
  • Evidence: Closed-loop Mermaid diagram, 2x close-up (fence extracted verbatim from README.md) (local file: /tmp/no-mistakes-evidence/01KYH47XZ1DDQ3TXT7C6ZJHZMS/04-closed-loop-diagram.png)
  • Evidence: Full README render - existing Architecture ASCII diagram and text loop left intact (local file: /tmp/no-mistakes-evidence/01KYH47XZ1DDQ3TXT7C6ZJHZMS/03-readme-full-page.png)
Evidence: Mermaid render verification (fence, diagnostics, SVG edge topology)

== headless Chromium render of README.md (mermaid 11.12, theme default, securityLevel strict) == <title>rendered:ok docHeight=4569 mermaidBlocks=1 flowchartSvgs=1</title> == edge ids in the rendered flowchart SVG (proves loop topology) == B -> E E -> B E -> M M -> P P -> B W -> B (M->P->B->E->M closes the cycle; E->B rollback; W->B watchdog revert via broker) == mermaid syntax-error strings in rendered DOM == 0

== mermaid fence extracted verbatim from README.md ==
mermaid fence extracted from README.md:
flowchart LR
    M["Measure<br/>FPS, latency,<br/>frametimes, thermals"]
    P["Policy engine<br/>decide bounded<br/>adjustment"]
    B["Broker<br/>apply via typed capability<br/>snapshot + TTL lease"]
    E["Evaluator<br/>keep or roll back"]
    W["Watchdog<br/>out-of-band guard<br/>lease/TTL + safety"]
    M --> P
    P --> B
    B --> E
    E -->|keep, iterate| M
    E -.->|roll back<br/>regression| B
    W -.->|lease/TTL expiry or safety violation:<br/>revert to snapshot| B


== headless Chromium render of README.md (mermaid 11.12, theme default, securityLevel strict) ==
<title>rendered:ok docHeight=4569 mermaidBlocks=1 flowchartSvgs=1</title>

== edge ids in the rendered flowchart SVG (proves loop topology) ==
B -> E
E -> B
E -> M
M -> P
P -> B
W -> B
(M->P->B->E->M closes the cycle; E->B rollback; W->B watchdog revert via broker)

== mermaid syntax-error strings in rendered DOM ==
0
Evidence: Self-contained rendered README (open in any browser; Mermaid renders live)
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>README.md - rendered</title>
<link rel="stylesheet" href="assets/github-markdown.css">
<script src="assets/marked.min.js"></script>
<style>
  body { margin: 0; background: #ffffff; }
  .page { max-width: 1012px; margin: 0 auto; padding: 32px; box-sizing: border-box; }
  .filebar {
    border: 1px solid #d1d9e0; border-bottom: none; border-radius: 6px 6px 0 0;
    background: #f6f8fa; padding: 10px 16px; font: 600 14px/20px -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
    color: #1f2328;
  }
  .filebody { border: 1px solid #d1d9e0; border-radius: 0 0 6px 6px; padding: 32px; }
  .markdown-body { font-size: 16px; }
  /* GitHub alert styling (github-markdown-css 5.8 ships .markdown-alert rules) */
</style>
</head>
<body>
<div class="page">
  <div class="filebar">README.md</div>
  <div class="filebody"><article class="markdown-body" id="content"></article></div>
</div>
<script id="src" type="text/plain"></script>
<script>
  window.__MD__ = "# FPSMaxxing\n\n**Autonomous, measurement-driven system performance tuning.**\n\nFPSMaxxing is an open-source Rust control plane for using an AI coding agent or LLM - such as Claude, Codex, or another MCP client - to improve gaming FPS, frame pacing, system latency, thermals, power efficiency, and compute throughput through bounded, reversible experiments.\n\n> [!IMPORTANT]\n> FPSMaxxing is currently a read-only alpha built around a mock provider.\n> An MCP client can discover typed capabilities and run the full snapshot, preview, apply, verify, and rollback lifecycle, but FPSMaxxing does **not** perform real hardware writes, overclock a GPU, edit BIOS settings, or modify the Windows Registry yet.\n\n## The closed loop\n\nFPSMaxxing is designed as a closed feedback loop that tunes system and hardware performance through bounded, reversible experiments.\n\n`` `mermaid\nflowchart LR\n    M[\"Measure<br/>FPS, latency,<br/>frametimes, thermals\"]\n    P[\"Policy engine<br/>decide bounded<br/>adjustment\"]\n    B[\"Broker<br/>apply via typed capability<br/>snapshot + TTL lease\"]\n    E[\"Evaluator<br/>keep or roll back\"]\n    W[\"Watchdog<br/>out-of-band guard<br/>lease/TTL + safety\"]\n    M --> P\n    P --> B\n    B --> E\n    E -->|keep, iterate| M\n    E -.->|roll back<br/>regression| B\n    W -.->|lease/TTL expiry or safety violation:<br/>revert to snapshot| B\n`` `\n\nAn MCP agent reaches the machine only through the unprivileged **gateway**, which exposes typed MCP tools instead of a shell, administrator credentials, or raw device access.\nThe gateway forwards a proposed experiment to the **capability registry and policy engine**, which intersects it with provider limits and reduces it to a single bounded, reversible adjustment.\nThe **privileged broker** is designed to apply that adjustment through a **provider sidecar**, always capturing a pre-state snapshot, holding a TTL lease, and recording every stage in the **durable experiment journal**.\nAn **independent watchdog** will own the lease deadline and restore the snapshot through the broker, without the gateway, agent, or experiment runner, whenever a lease expires or a safety violation appears.\nIn the target design the loop then re-measures under workload, and the **deterministic evaluator** - kept outside the LLM's writable surface - decides from those measurements whether to keep the change or roll back a regression before the next iteration begins.\n\n## Why FPSMaxxing?\n\nExisting tools already know how to control parts of a PC:\n\n- Process Lasso manages process priorities, CPU sets, affinities, and power profiles.\n- Fan Control manages fan curves and thermal response.\n- PresentMon measures frame times, latency, and rendering performance.\n- LibreHardwareMonitor reads clocks, temperatures, fan speeds, loads, and power.\n- NVML and AMD SMI expose supported GPU telemetry and controls.\n- Windows APIs expose power policy and documented Registry settings.\n\nFPSMaxxing is intended to connect those control planes to a reproducible research loop:\n\n`` `text\nobserve → propose → validate → snapshot → apply → benchmark → keep or rollback\n`` `\n\nThe LLM proposes an experiment. Deterministic policy, broker, provider, watchdog, and measurement components decide whether the experiment is allowed and whether its measured result should be retained.\n\n## Design principles\n\n- **The model is never the root process.** Privileged changes pass through a small Rust broker.\n- **Capabilities, not shell commands.** Agents call typed operations with bounded parameters.\n- **Every write is leased.** Changes require a snapshot, verification probe, deadline, and rollback path.\n- **One owner per knob.** Conflicting tuning applications cannot fight over the same setting.\n- **Measurement beats folklore.** Changes survive only when repeated workload tests show a practical improvement.\n- **Fast loops stay local.** Drivers and dedicated tools control millisecond-to-second behavior; the LLM operates at experiment cadence.\n\n## Planned integrations\n\n| Area | Initial provider | Intended use |\n| --- | --- | --- |\n| Process scheduling | Process Lasso | CPU affinity, CPU sets, priorities, process power profiles |\n| Frame performance | PresentMon | FPS, frame time, latency, GPU telemetry |\n| Hardware telemetry | LibreHardwareMonitor bridge | Temperatures, clocks, loads, power, fan RPM |\n| Fan control | Fan Control | Complete, reviewed thermal profiles |\n| NVIDIA GPU | NVML | Supported clock and power-limit operations |\n| AMD GPU | AMD SMI | Supported telemetry and control operations |\n| Windows power | Native Windows APIs | Cloned power schemes and processor policy |\n| Registry | Curated catalog | Documented, typed, versioned, reversible settings only |\n\nBIOS changes, voltage changes, raw MSR/PCI/EC access, firmware flashing, and arbitrary Registry paths are explicitly outside the first release.\n\n## Repository status\n\nThe repository currently includes:\n\n- A Rust 2024 Cargo workspace\n- Shared capability and provider contracts\n- A provider SDK lifecycle\n- A working mock provider with snapshot/preview/apply/verify/rollback tests\n- A control-plane crate holding the capability registry, bounded policy, broker lifecycle, and durable SQLite experiment journal\n- A working stdio MCP gateway that serves the mock path end to end\n- A CLI `doctor` command that reports gateway and journal status\n- Scaffolds for the privileged broker, watchdog, and experiment runner\n- OSS governance, security policy, issue templates, and CI\n- An organized [documentation index](docs/README.md) with architecture, plans, threat model, and provider guides\n\nTry the read-only alpha:\n\n`` `bash\ncargo test --workspace\ncargo run -p fpsmaxxing-cli -- doctor\ncargo run -p fpsmaxxing-mock-provider\nprintf '%s\\n' \\\n  '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}' \\\n  '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"fpsmaxxing.run_mock_lifecycle\",\"arguments\":{\"value\":42,\"lease_seconds\":30}}}' \\\n  | cargo run -p fpsmaxxing-gateway\n`` `\n\nThe gateway speaks line-delimited JSON-RPC (MCP) on stdio and journals every lifecycle stage attempt plus a terminal outcome to `fpsmaxxing-journal.sqlite` by default.\nOverride the journal location with `--journal <path>` or the `FPSMAXXING_JOURNAL_PATH` environment variable; `doctor` reads the same variable when reporting journal status.\n\n## Architecture\n\n`` `text\nLLM / MCP client\n       │\n       ▼\nRust gateway ──► policy engine ──► privileged broker ──► provider sidecars\n       ▲                                  │\n       │                                  ▼\ntelemetry normalizer ◄──────────── independent watchdog\n       │\n       ▼\nexperiment journal and benchmark decision gate\n`` `\n\n## Documentation\n\nStart with the [documentation index](docs/README.md). The core references are the [architecture](docs/ARCHITECTURE.md), implementation plan in [Markdown](docs/IMPLEMENTATION_PLAN.md) or [HTML](docs/IMPLEMENTATION_PLAN.html), [threat model](docs/threat-model/README.md), and [agent instructions](AGENTS.md).\n\n## Frequently asked questions\n\n### Can Claude optimize my PC for higher FPS?\n\nThat is the intended workflow. A Claude or Codex agent should be able to inspect available capabilities, propose a bounded change, run a controlled game or benchmark workload, and keep the change only when frame time, latency, thermals, and correctness remain within policy. The alpha already runs capability discovery and the bounded snapshot-to-rollback lifecycle over MCP against a mock provider; the measurement-driven keep-or-rollback decision and real hardware providers are not implemented yet.\n\n### Can an AI safely overclock a GPU?\n\nFPSMaxxing will not expose arbitrary voltage or register writes. Planned GPU operations use supported vendor APIs, query device limits first, require rollback, and run under an independent thermal watchdog. Persistent or high-risk operations require explicit approval.\n\n### Is this an AI BIOS optimizer?\n\nNot initially. Consumer BIOS settings are vendor-specific and can make a machine unbootable. Server firmware may eventually be supported through Redfish and boot recovery, but firmware autonomy is deliberately deferred.\n\n### Does FPSMaxxing replace Process Lasso, Fan Control, or MSI Afterburner?\n\nNo. It is an orchestration and measurement layer. Where a stable third-party control plane exists, FPSMaxxing should integrate with it instead of reimplementing its hardware logic.\n\n### Will it blindly apply Windows performance tweaks from the internet?\n\nNo. Registry and power changes must come from a curated catalog containing the supported Windows versions, exact value type, permitted values, verification method, risk class, and rollback procedure.\n\n## Contributing\n\nRead [CONTRIBUTING.md](CONTRIBUTING.md) and the current [implementation plan](docs/IMPLEMENTATION_PLAN.md) before starting a provider. Security-sensitive changes require tests for denial, timeout, lease expiry, verification failure, and rollback.\n\n## Security\n\nDo not open public issues for vulnerabilities that could enable arbitrary privileged execution or unsafe hardware writes. Follow [SECURITY.md](SECURITY.md).\n\n## License\n\nLicensed under the [Apache License 2.0](LICENSE).\n";
</script>
<script>
  marked.setOptions({ gfm: true, breaks: false });
  let out = marked.parse(window.__MD__);
  const el = document.getElementById("content");
  el.innerHTML = out;

  // GitHub-style heading anchors so screenshots can target a section by #fragment.
  el.querySelectorAll("h1,h2,h3,h4").forEach((h) => {
    h.id = h.textContent.trim().toLowerCase().replace(/[^a-z0-9 -]/g, "").replace(/\s+/g, "-");
  });

  // GitHub alert blocks: > [!IMPORTANT] ... -> styled callout
  const ALERTS = { NOTE: "Note", TIP: "Tip", IMPORTANT: "Important", WARNING: "Warning", CAUTION: "Caution" };
  const OCTICON = {
    IMPORTANT: '<svg class="octicon" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg>'
  };
  el.querySelectorAll("blockquote > p:first-child").forEach((p) => {
    const m = /^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*(<br\s*\/?>)?/i.exec(p.innerHTML.trim());
    if (!m) return;
    const kind = m[1].toUpperCase();
    const bq = p.parentElement;
    p.innerHTML = p.innerHTML.replace(m[0], "");
    const div = document.createElement("div");
    div.className = "markdown-alert markdown-alert-" + kind.toLowerCase();
    const title = document.createElement("p");
    title.className = "markdown-alert-title";
    title.innerHTML = (OCTICON[kind] || "") + ALERTS[kind];
    div.appendChild(title);
    while (bq.firstChild) div.appendChild(bq.firstChild);
    bq.replaceWith(div);
  });

  // GitHub renders `` `mermaid blocks natively; mermaid.js does the same job here.
  el.querySelectorAll('pre > code.language-mermaid').forEach((code) => {
    const pre = code.parentElement;
    const holder = document.createElement("pre");
    holder.className = "mermaid";
    holder.textContent = code.textContent;
    pre.replaceWith(holder);
  });
  window.__MERMAID_BLOCKS__ = el.querySelectorAll("pre.mermaid").length;
</script>
<script src="assets/mermaid.min.js"></script>
<script>
  window.__MERMAID_ERROR__ = null;
  window.__MERMAID_DONE__ = false;
  mermaid.initialize({ startOnLoad: false, theme: "default", securityLevel: "strict" });
  (async () => {
    try {
      const blocks = [...document.querySelectorAll("pre.mermaid")];
      for (const b of blocks) { await mermaid.parse(b.textContent); }
      await mermaid.run({ nodes: blocks });
    } catch (e) {
      window.__MERMAID_ERROR__ = String((e && e.message) || e);
    } finally {
      window.__MERMAID_DONE__ = true;
      await new Promise((r) => setTimeout(r, 400));
      if (location.hash) {
        const target = document.querySelector(location.hash);
        if (target) window.scrollTo(0, target.getBoundingClientRect().top + window.scrollY - 24);
      }
      await new Promise((r) => setTimeout(r, 200));
      document.title = "rendered:" + (window.__MERMAID_ERROR__ ? "ERROR" : "ok")
        + " docHeight=" + document.documentElement.scrollHeight
        + " mermaidBlocks=" + window.__MERMAID_BLOCKS__
        + " flowchartSvgs=" + document.querySelectorAll('pre.mermaid svg').length;
    }
  })();
</script>
</body>
</html>
Evidence: Reproduction notes for the evidence pipeline
# How this evidence was produced

Goal: show what a reader actually sees when landing on `README.md`, including the new
`## The closed loop` Mermaid diagram, which GitHub renders client-side.

No browser was usable in this sandbox out of the box (bundled Chromium was missing ~19 shared
libraries, and the puppeteer build is x86_64 on an arm64 host). The Ubuntu arm64 runtime libs were
downloaded and unpacked into `/tmp/chrome-deps/root` and used via `LD_LIBRARY_PATH` only - no system
packages were installed and nothing outside this evidence directory was modified.

## Steps

1. `build-readme-page.mjs <README.md> readme-rendered.html`
   - embeds the file verbatim, renders it with `marked` (GFM), styles it with `github-markdown-css`,
     converts `> [!IMPORTANT]` into a GitHub alert, and hands the ` `` `mermaid ` fence to
     `mermaid@11.12` with `theme: default, securityLevel: strict` - the same client-side path GitHub uses.
2. `build-diagram-page.mjs <README.md> diagram-rendered.html`
   - extracts the single ` `` `mermaid ` fence straight out of `README.md` (fails if there is not exactly
     one) and renders it alone for a 2x close-up.
3. Screenshots with `headless_shell --screenshot` at 1280px content width (GitHub's `.markdown-body` is
   1012px max):
   - `00-readme-landing-BEFORE.png` - README at base commit `7f3ab1d`
   - `01-readme-landing-AFTER.png`  - README at `17e9381`
   - `03-readme-full-page.png`      - whole document, confirming the pre-existing `## Architecture`
     ASCII diagram and `observe -> propose -> ...` text loop are untouched
   - `04-closed-loop-diagram.png`   - 2x close-up of the rendered flowchart
4. `mermaid-render-verification.txt` - the extracted fence, the render diagnostics
   (`rendered:ok ... mermaidBlocks=1 flowchartSvgs=1`), and the edge ids found in the produced SVG,
   which pin the topology: `M->P->B->E->M` (cycle closes), `E->B` (rollback), `W->B` (watchdog reverts
   through the broker, i.e. not the inverted direction fixed in `17e9381`).

`dom.html` is the post-render DOM dump the edge-id check was run against.

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 4 issues found → auto-fixed (3) ✅
  • ⚠️ README.md:13 - The new section asserts the full loop in present tense as shipped behavior ("FPSMaxxing is a closed feedback loop that tunes...", "The privileged broker applies that adjustment through a provider sidecar", "An independent watchdog owns the lease deadline", "the deterministic evaluator ... decides whether to keep the change"). The README's own status list (line 89: "Scaffolds for the privileged broker, watchdog, and experiment runner"), the FAQ (line 131: "the measurement-driven keep-or-rollback decision and real hardware providers are not implemented yet"), and docs/ARCHITECTURE.md:5 all say otherwise, and the Measure node (FPS, latency, frametimes, thermals) describes telemetry adapters that also do not exist yet. Every other forward-looking part of this README is explicitly hedged ("is intended to connect", "Planned integrations", "will not expose"), so this section reads as the odd one out. Placing it immediately after the alpha IMPORTANT note helps but does not undo the present tense; one qualifying clause (e.g. "the target loop, today exercised end to end against a mock provider") would keep the punch without the overclaim.
  • ⚠️ README.md:24 - The flowchart puts the watchdog inline as a sequential stage (B --> W --> E), implying each experiment flows through the watchdog between apply and evaluate. The architecture is the opposite: the watchdog is an out-of-band supervisor that owns lease deadlines and can restore state without the gateway, agent, or runner (docs/ARCHITECTURE.md:19, docs/IMPLEMENTATION_PLAN.md:109), and the README's own ASCII diagram at lines 114-117 draws it as a side path rather than a step. As drawn, the diagram contradicts the independence invariant the prose one line below is selling. Modeling it as Broker --> Evaluator for the normal path, with the watchdog hanging off the broker via a dashed "regression / lease expiry -> revert" edge, would match both the docs and the prose.
  • ℹ️ README.md:16 - The prose names seven pieces (gateway, capability registry + policy engine, privileged broker, provider sidecars, durable experiment journal, independent watchdog, deterministic evaluator) but the diagram shows five nodes and shares only three of those names; the unprivileged gateway, provider sidecars, and experiment journal - including the gateway, which is the main safety boundary being sold - are absent from the visual. A reader who maps the picture onto the paragraph will not find the trust boundary in the picture.
  • ℹ️ README.md:15 - The README now carries three overlapping depictions of the same pipeline: this Mermaid cycle (lines 15-27), the "observe -> propose -> validate -> snapshot -> apply -> benchmark -> keep or rollback" text loop (line 49), and the ASCII architecture diagram (lines 110-121), which use three different vocabularies for the same stages ("benchmark"/"Evaluator"/"benchmark decision gate"). Keeping all three was deliberate, but they will drift independently as the implementation lands; consider dropping or folding the line-49 text loop into the new section, since it is the closest duplicate.

🔧 Fix: hedge closed-loop README claims and draw watchdog out-of-band
2 infos still open:

  • ℹ️ README.md:34 - The watchdog is described (line 34: "restore the snapshot ... whenever a regression or safety violation appears") and drawn (line 27: M -.->|regression or safety violation| W) as owning revert-on-regression, while the same diagram gives E["Evaluator keep or roll back"] that decision and line 35 says the evaluator "decides whether to keep the change or roll it back". docs/ARCHITECTURE.md:19 scopes the watchdog to lease deadlines and emergency rollback; docs/ARCHITECTURE.md:23 gives promotion/rollback decisions to the runner/evaluator, and docs/IMPLEMENTATION_PLAN.md:109 requires the watchdog to be independent of the experiment runner - yet the diagram's only trip input for W comes from the runner's Measure stage. Scoping the watchdog edge to safety violations and lease expiry (its documented job) and leaving performance regressions to the evaluator would keep the two roles distinct instead of overlapping. This is close to the captain's original "revert on regression or safety violation" wording, so it needs the author's call.
  • ℹ️ README.md:28 - The recovery edge is drawn as W -.->|revert to snapshot| M, pointing the watchdog's restore at the Measure stage. Every other depiction in the repo routes recovery through the broker/provider layer that actually holds the applied state: README.md:116-119 (broker -> independent watchdog), docs/IMPLEMENTATION_PLAN.md:26 (broker with an independent watchdog and rollback branch), and docs/IMPLEMENTATION_PLAN.html:110 (WATCH -->|"trip / TTL expiry"| BROKER). As drawn, no edge shows the applied change being undone on the machine, so the dashed path reads as "the watchdog triggers a re-measure" rather than "the watchdog restores hardware state". Retargeting the dashed revert edge at B keeps the watchdog out-of-band (it is still not on the M -> P -> B -> E path) while showing where the snapshot is actually restored.

🔧 Fix: scope watchdog to lease/safety; route reverts through broker
1 warning still open:

  • ⚠️ README.md:27 - The trip edge is drawn as B -.-&gt;|lease/TTL expiry or safety violation| W, i.e. the broker detects expiry and notifies the watchdog. That inverts ownership relative to the prose one line below (line 34: "An independent watchdog will own the lease deadline"), docs/ARCHITECTURE.md:19 ("The independent watchdog owns lease deadlines and emergency rollback"), and docs/IMPLEMENTATION_PLAN.md:59 ("If the gateway, workload, or agent dies, the watchdog restores the prior state") - the whole point is that the watchdog fires when nobody is left to signal it. The repo's other Mermaid diagram draws it the other way: docs/IMPLEMENTATION_PLAN.html:110 is WATCH[&#34;Independent watchdog service&#34;] --&gt;|&#34;trip / TTL expiry&#34;| BROKER. The direction change from the previous round's M -.-&gt; W to B -.-&gt; W was not part of the round-2 instruction (only the label and the W->B revert target were), so this looks incidental. Two edges between B and W is fine if the labels match their direction: label B -.-&gt; W as the arming/registration step (e.g. "register lease + snapshot") and move the trip condition onto the existing W -.-&gt; B edge (e.g. "lease/TTL expiry or safety violation: revert to snapshot"), which keeps both the out-of-band styling and the correct detector.

🔧 Fix: fix inverted watchdog trip edge in closed-loop diagram
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • node build-readme-page.mjs README.md readme-rendered.html - renders README.md with GFM + github-markdown-css + mermaid 11.12 (theme default, securityLevel strict), the same client-side path GitHub uses
  • headless_shell --screenshot --window-size=1280,1500 on the target-commit render - captured 01-readme-landing-AFTER.png (reader's landing view)
  • git show 7f3ab1d:README.md rendered identically and captured as 00-readme-landing-BEFORE.png for the before/after comparison
  • headless_shell --screenshot --window-size=1280,4600 - full-page render confirming the existing ## Architecture ASCII diagram and observe -&gt; propose ... text loop are unchanged
  • node build-diagram-page.mjs README.md diagram-rendered.html - extracts the single ```mermaid fence verbatim from README.md (asserts exactly one) and renders it standalone at 2x for 04-closed-loop-diagram.png
  • headless_shell --dump-dom + grep -o &#39;id=&#34;L_[A-Za-z_0-9]*&#34;&#39; on the rendered SVG - asserts edges M->P, P->B, B->E, E->M, E->B, W->B and grep -ci &#39;syntax error&#39; == 0
  • Render diagnostics from the page title: rendered:ok docHeight=4569 mermaidBlocks=1 flowchartSvgs=1
  • Doc-grounding check: grep -ci for each named component across README.md, docs/ARCHITECTURE.md, docs/IMPLEMENTATION_PLAN.md, plus line-level match of the watchdog-independence, evaluator-outside-LLM, and intersect-with-provider-limits claims
  • CC=/tmp/zig-shim/cc AR=/tmp/zig-shim/ar RANLIB=/tmp/zig-shim/ranlib cargo test --workspace --locked - full suite green after shimming the sandbox's C toolchain
  • git status --porcelain --ignored after removing the target/ build output - worktree left clean
🔧 **Document** - 1 issue found → auto-fixed ✅
  • ⚠️ README.md:118 - The legacy ASCII diagram in '## Architecture' contradicts the new Mermaid closed-loop diagram on the watchdog relationship. The ASCII draws privileged broker -> independent watchdog -> telemetry normalizer -> gateway, while README.md:27 (new) and docs/IMPLEMENTATION_PLAN.html:110 both draw watchdog -> broker ('trip / TTL expiry'). No document anywhere supports a watchdog -> telemetry normalizer edge. Left unresolved because the author's stated intent was to keep the ASCII diagram in place as a separate view, and fixing it requires a judgment call: redraw the ASCII arrows to match, or drop the ASCII diagram now that a GitHub-native Mermaid diagram covers the same flow ~90 lines above it.

🔧 Fix: correct watchdog arrows in README architecture diagram
✅ Re-checked - no issues remain.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

undeemed added 6 commits July 27, 2026 06:16
Add a Mermaid feedback-loop diagram and a short prose walkthrough right
after the intro, so a reader instantly grasps that FPSMaxxing is a closed
loop: measure -> policy decides bounded adjustment -> broker applies via
typed capability (snapshot + TTL lease) -> watchdog reverts on regression
or safety violation -> deterministic evaluator keeps or rolls back, then
iterate. Names the gateway, capability/policy registry, broker, provider
sidecars, durable journal, independent watchdog, and evaluator, keeping
the safety invariants (no shell/admin to the LLM, snapshot+TTL+rollback
on every write, independent watchdog) visible. Grounded in ARCHITECTURE.md
and IMPLEMENTATION_PLAN.md; docs-only.
@undeemed
undeemed merged commit d63f157 into main Jul 28, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant