Skip to content

docs(readme): re-cut README as one document and relocate broker operations - #15

Merged
undeemed merged 10 commits into
mainfrom
fm/fpsm-readme-cut-r3
Jul 29, 2026
Merged

docs(readme): re-cut README as one document and relocate broker operations#15
undeemed merged 10 commits into
mainfrom
fm/fpsm-readme-cut-r3

Conversation

@undeemed

Copy link
Copy Markdown
Owner

Intent

Docs-only re-cut of README.md so it reads as one designed document instead of accreted per-PR sections. Five ordered defects, all decided by the captain up front: (1) the ~48-line 'Privileged broker' section was wildly out of proportion, so its filesystem-permission reference material (sticky bits, why /tmp and merely-traversable /run are refused, XDG_RUNTIME_DIR vs the single-instance lock, systemd RuntimeDirectoryMode 0755, recovery from wrong-owner /run/fpsmaxxing, flag/env precedence) was RELOCATED IN FULL to a new docs/BROKER_OPERATIONS.md and registered in the docs/README.md index table; the README keeps under 10 lines plus a link. Deleting that material was explicitly forbidden. (2) Tense was incoherent: prose described the watchdog and experiment runner as future while the status list described them as present. Convention now is present tense for what is implemented, explicit future tense for what is not, with the alpha 'not on real hardware yet' caveat stated once prominently instead of hedging every sentence. (3) The same pipeline was drawn four times; the Mermaid diagram and the prose walkthrough stay, the redundant arrow text block and the ASCII architecture diagram were cut. (4) 'Repository status' was a 13-bullet merge-history changelog and is now organised by capability, not by PR. (5) The first FAQ answer was a five-sentence wall and now leads with the direct answer then the caveat. Hard constraints: no changes under src/ or crates/, no code refactors to satisfy a gate. The '## The closed loop' section and its Mermaid diagram are protected by direct captain order and must stay near the top substantively unchanged. Repo Markdown convention is one full sentence per line and plain dashes only - README must contain zero em dashes. This branch already carries six earlier review fix rounds; the prior pipeline run died to an out-of-memory kill, not to findings, so this is a clean re-run of reviewed content.

What Changed

  • Re-cut README.md as a single document: the alpha caveat and a stated tense convention (present tense for what runs today on the mock path, future tense for what does not exist yet) now sit up front, the closed-loop walkthrough is split accordingly, Repository status is regrouped by capability instead of listing merge history, and the first FAQ answer leads with the direct answer before the caveat. The protected ## The closed loop section and its Mermaid diagram are unchanged; the duplicate arrow-text pipeline and the ASCII architecture diagram are removed.
  • Moved the broker filesystem reference material (private-directory ownership rules, why /tmp and merely-traversable /run are refused, XDG_RUNTIME_DIR versus the single-instance lock, systemd RuntimeDirectoryMode, flag/environment precedence, recovery from a wrong-owner /run/fpsmaxxing) out of the ~48-line README section into a new docs/BROKER_OPERATIONS.md, registered under a new Operations table in the docs/README.md index. The README keeps a short broker summary plus the link.
  • Corrected the FPSMAXXING_JOURNAL_PATH ownership statement to name the gateway, CLI, and watchdog in README.md, docs/ARCHITECTURE.md, and the apps/broker/src/main.rs doc comments, and reworded the Windows named-pipe transport there as not yet available rather than deliberately out of scope. The Rust change is doc comments only, no code or behavior.

Risk Assessment

✅ Low: Docs-only change across four Markdown files with no source edits; every factual claim in the re-cut README was verified against the corresponding code (watchdog journal env, broker cfg(unix) gate, evaluator-before-apply ordering, CLI flags), the relocated broker reference material is present in full in docs/BROKER_OPERATIONS.md with nothing dropped, and the previously flagged 32MB core dump is confirmed unreachable from every ref.

Testing

Ran the full workspace test suite (170 pass, 0 fail) as a regression baseline, then produced the evidence that actually matters for a docs re-cut: rendered before/after screenshots of README.md plus the new docs/BROKER_OPERATIONS.md and the docs index, showing the broker section cut from ~49 lines to 11 plus a link, the tense caveat consolidated at the top, the pipeline drawn once with the protected Mermaid diagram byte-identical, Repository status regrouped by capability, and the first FAQ answer leading with the direct answer. Confirmed the relocated filesystem-permission material survives in full in the new page and no longer in the README, the page is registered in the docs index, all 23 relative links resolve, there are zero em dashes, and nothing under src/ or crates/ was touched. Also ran the README's own quickstart (doctor, experiment runner, stdio MCP gateway with a real JSON-RPC transcript and journal rows) and the watchdog/broker env-var check, so the re-cut's present-tense claims are backed by working commands rather than prose alone. No failures; the only note is that the stated target commit carries a stray 33 MB core dump that the checked-out HEAD already removed.

  • Evidence: README.md AFTER - full page rendered (branch HEAD 3e4c075) (local file: /tmp/no-mistakes-evidence/01KYN9ZT3RVCB0ENJP1SF2ZZMR/02-readme-AFTER-3e4c075.png)
  • Evidence: README.md AFTER - top half (caveat block, protected closed-loop Mermaid, single prose walkthrough, reformatted integrations table) (local file: /tmp/no-mistakes-evidence/01KYN9ZT3RVCB0ENJP1SF2ZZMR/02a-readme-AFTER-top.png)
  • Evidence: README.md AFTER - bottom half (capability-grouped status, 11-line broker section with link, split FAQ answer, no ASCII Architecture section) (local file: /tmp/no-mistakes-evidence/01KYN9ZT3RVCB0ENJP1SF2ZZMR/02b-readme-AFTER-bottom.png)
  • Evidence: README.md BEFORE - bottom half (49-line broker wall, ASCII Architecture diagram, five-sentence FAQ answer) (local file: /tmp/no-mistakes-evidence/01KYN9ZT3RVCB0ENJP1SF2ZZMR/01b-readme-BEFORE-base-bottom.png)
  • Evidence: README.md BEFORE - top half (base 9e76b27, redundant arrow text block, 12-bullet merge-history status) (local file: /tmp/no-mistakes-evidence/01KYN9ZT3RVCB0ENJP1SF2ZZMR/01a-readme-BEFORE-base-top.png)
  • Evidence: docs/BROKER_OPERATIONS.md - new page holding the relocated reference material in full (local file: /tmp/no-mistakes-evidence/01KYN9ZT3RVCB0ENJP1SF2ZZMR/03-docs-BROKER_OPERATIONS-new.png)
  • Evidence: docs/README.md - new Operations index row registering the page (local file: /tmp/no-mistakes-evidence/01KYN9ZT3RVCB0ENJP1SF2ZZMR/04-docs-index-operations-row.png)
Evidence: README quickstart - MCP gateway JSON-RPC transcript, doctor, and journal rows

$ printf ... | cargo run -p fpsmaxxing-gateway {"id":1,"result":{"tools":[{"name":"fpsmaxxing.capabilities",...},{"name":"fpsmaxxing.run_mock_lifecycle",...}]}} {"id":2,"result":{"content":[{"text":"{"provider_id":"mock","preview":"set mock.value from 0 to 42","verified":true,"rolled_back":true}"}]}} $ cargo run -p fpsmaxxing-cli -- doctor # after the run journal: ready (/tmp/.../fpsmaxxing-journal.sqlite) status: read-only alpha mock path ready $ sqlite3 journal: lifecycle stages recorded table experiment_journal = 8 rows

$ export FPSMAXXING_JOURNAL_PATH=/tmp/tmp.jPF1KVv0WZ/fpsmaxxing-journal.sqlite
$ printf ... | cargo run -p fpsmaxxing-gateway
{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "tools": [
      {
        "description": "Discover typed, policy-approved capabilities",
        "inputSchema": {
          "additionalProperties": false,
          "type": "object"
        },
        "name": "fpsmaxxing.capabilities"
      },
      {
        "description": "Run snapshot, preview, apply, verify, and rollback for mock.value",
        "inputSchema": {
          "additionalProperties": false,
          "properties": {
            "lease_seconds": {
              "maximum": 300,
              "minimum": 1,
              "type": "integer"
            },
            "value": {
              "maximum": 100,
              "minimum": 0,
              "type": "integer"
            }
          },
          "required": [
            "value",
            "lease_seconds"
          ],
          "type": "object"
        },
        "name": "fpsmaxxing.run_mock_lifecycle"
      }
    ]
  }
}
{
  "id": 2,
  "jsonrpc": "2.0",
  "result": {
    "content": [
      {
        "text": "{\"provider_id\":\"mock\",\"preview\":\"set mock.value from 0 to 42\",\"verified\":true,\"rolled_back\":true}",
        "type": "text"
      }
    ]
  }
}

$ cargo run -p fpsmaxxing-cli -- doctor   # after the run
FPSMaxxing diagnostics
  contracts: ready
  provider SDK: ready
  gateway: MCP mock path available
  journal: ready (/tmp/tmp.jPF1KVv0WZ/fpsmaxxing-journal.sqlite)
  hardware writes: disabled
  status: read-only alpha mock path ready

$ sqlite3 journal: lifecycle stages recorded
table experiment_journal = 8 rows
table experiment_trials = 0 rows
Evidence: Journal env-var ownership - the corrected README sentence, demonstrated

$ cargo run -p fpsmaxxing-cli -- doctor # CLI honours it journal: ready (/tmp/.../unprivileged-journal.sqlite) $ cargo run -p fpsmaxxing-broker -- --help # broker: own vars only --socket <path> (environment: FPSMAXXING_BROKER_SOCKET) --journal <path> (environment: FPSMAXXING_BROKER_JOURNAL_PATH) $ FPSMAXXING_JOURNAL_PATH=/nonexistent-dir-xyz/journal.sqlite cargo run -p fpsmaxxing-watchdog -- --once Error: Journal(... "unable to open database file: /nonexistent-dir-xyz/journal.sqlite") (exit non-zero naming the env-var path -> the watchdog does read FPSMAXXING_JOURNAL_PATH)

# README claim under test:
#   "FPSMAXXING_JOURNAL_PATH belongs to the unprivileged tools - the gateway, the CLI,
#    and the watchdog - and the privileged broker deliberately does not read it."

$ export FPSMAXXING_JOURNAL_PATH=/tmp/tmp.Tjcue63DBO/unprivileged-journal.sqlite

$ printf ... | cargo run -p fpsmaxxing-gateway   # gateway honours it
   -> journal created at $FPSMAXXING_JOURNAL_PATH: yes

$ cargo run -p fpsmaxxing-cli -- doctor          # CLI honours it
  journal: ready (/tmp/tmp.Tjcue63DBO/unprivileged-journal.sqlite)

$ cargo run -p fpsmaxxing-watchdog -- --once     # watchdog honours it

$ cargo run -p fpsmaxxing-broker -- --help | grep -A1 journal   # broker: own var only
Usage: fpsmaxxing-broker [--socket <path>] [--journal <path>]

  --socket <path>   Unix domain socket to listen on
                    (environment: FPSMAXXING_BROKER_SOCKET)
  --journal <path>  SQLite audit journal to write
                    (environment: FPSMAXXING_BROKER_JOURNAL_PATH)
  -h, --help        Print this message and exit


$ FPSMAXXING_JOURNAL_PATH=/nonexistent-dir-xyz/journal.sqlite cargo run -p fpsmaxxing-watchdog -- --once
Error: Journal(SqliteFailure(Error { code: CannotOpen, extended_code: 14 }, Some("unable to open database file: /nonexistent-dir-xyz/journal.sqlite")))
   (exit non-zero naming the env-var path -> the watchdog does read FPSMAXXING_JOURNAL_PATH)
Evidence: Structural checks - scope, em dashes, diagram dedupe, relocation completeness, index registration, link resolution

1. Scope: README.md, docs/ARCHITECTURE.md, docs/BROKER_OPERATIONS.md, docs/README.md files under src/ or crates/: 0 2. Em dashes: README=0 BROKER_OPERATIONS=0 docs/README=0 3. mermaid fences base=1 head=1 (block byte-identical) "observe -> propose ..." block base=1 head=0 "## Architecture" ASCII block base=1 head=0 4. Privileged broker section: base=49 lines head=11 lines 5. sticky bit / merely traversable / XDG_RUNTIME_DIR / broker.lock / RuntimeDirectoryMode / chowned to root / flag-wins-over-env: all present in BROKER_OPERATIONS, all 0 in README 7. status bullets: base 12 flat merge-history -> head 6 capability groups 8. All relative links resolve: 0 broken (23 checked)

README re-cut - structural checks (base 9e76b27 -> HEAD 3e4c075)

1. Scope: no code touched
README.md
docs/ARCHITECTURE.md
docs/BROKER_OPERATIONS.md
docs/README.md
   files under src/ or crates/: 0

2. Em dashes (U+2014) - repo convention is plain dashes
   README.md                  0
   docs/BROKER_OPERATIONS.md  0
   docs/README.md             0

3. Pipeline drawn once: Mermaid kept, arrow text block + ASCII diagram cut
   mermaid fences in README        base=1 head=1 (block byte-identical)
   "observe -> propose ..." block  base=1 head=0
   "## Architecture" ASCII block   base=1 head=0

4. Privileged broker section length (lines between its heading and the next)
   base=49  head=11

5. Relocated reference material now lives in docs/BROKER_OPERATIONS.md
   sticky bit                                 BROKER_OPERATIONS=1  README=0
   /tmp                                       BROKER_OPERATIONS=1  README=0
   merely traversable                         BROKER_OPERATIONS=1  README=0
   /run                                       BROKER_OPERATIONS=6  README=0
   XDG_RUNTIME_DIR                            BROKER_OPERATIONS=3  README=0
   broker.lock                                BROKER_OPERATIONS=2  README=0
   RuntimeDirectoryMode                       BROKER_OPERATIONS=1  README=0
   chowned to root                            BROKER_OPERATIONS=1  README=0
   A flag wins over its environment variable  BROKER_OPERATIONS=1  README=0

6. Registered in the docs index
18:| [Broker operations and deployment](BROKER_OPERATIONS.md) | Running the privileged broker: socket, journal, and lock paths, private-directory ownership rules, and systemd units |

7. Repository status organised by capability, not by PR
   base: 12 flat merge-history bullets, e.g.
      - A Rust 2024 Cargo workspace
      - Shared capability and provider contracts
      - A provider SDK lifecycle
      - A working mock provider with snapshot/preview/apply/verify/rollback tests
      ... (8 more)
   head: 6 capability groups:
      - Capabilities and providers
      - Policy and journal
      - Agent surface
      - Privileged boundary
      - Crash and lease recovery
      - Measurement and decision

8. All relative links in the three touched docs resolve: 0 broken (23 checked)
Evidence: Self-contained rendered HTML (open in any browser)
<!doctype html>
<html><head><meta charset="utf-8"><title>README.md  -  AFTER (branch fm/fpsm-readme-cut-r3 @ 3e4c075)</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@5.8.1/github-markdown-light.min.css">
<script src="https://cdn.jsdelivr.net/npm/marked@12.0.2/marked.min.js"></script>
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10.9.1/dist/mermaid.esm.min.mjs';
window.__mermaid = mermaid;
</script>
<style>
 body{margin:0;background:#fff}
 .banner{font:600 15px/1.4 -apple-system,Segoe UI,sans-serif;background:#0969da;color:#fff;padding:10px 24px}
 .markdown-body{box-sizing:border-box;max-width:1012px;margin:0 auto;padding:32px 24px 64px}
 .mermaid{background:#fff;padding:8px 0}
</style>
</head><body>
<div class="banner">README.md  -  AFTER (branch fm/fpsm-readme-cut-r3 @ 3e4c075)</div>
<article class="markdown-body" id="out"></article>
<script type="module">
const 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> Measurement is a deterministic stand-in for live telemetry, and the gateway does not route through the privileged broker yet.\n>\n> Every claim below about what the system does is written in the present tense for what runs today on that mock path, and in the future tense for what does not exist yet; the design principles and the planned integrations state intent rather than status.\n> Read every present-tense claim against this caveat rather than as a claim about real hardware.\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 -->|re-measure under workload| 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** applies that adjustment across the local IPC boundary, always capturing a pre-state snapshot, holding a TTL lease, and recording every stage in the **durable experiment journal**.\nThe gateway does not reach the broker over that boundary yet; today it drives a control plane of its own in process, under those same snapshot, lease, and journal rules.\nThe broker will reach the hardware through a **provider sidecar**; today that in-process control plane links its provider directly.\nAn **independent watchdog** owns the lease deadline and restores the snapshot from the journal, without the gateway, agent, or experiment runner, whenever a lease expires or a crash leaves an experiment unclosed.\nIt will perform that restore through the broker, and will also trigger on a safety violation.\nThe **deterministic evaluator** - kept outside the LLM's writable surface - decides from the recorded measurements whether the candidate is applied at all.\nThe loop will re-measure under workload inside the lease window; today it measures the candidate before the apply.\nThat same verdict will decide whether an improvement persists past its lease or is rolled back as a regression, and will drive the next iteration of the loop.\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 will connect those control planes to the reproducible research loop described above; today only the mock provider is wired.\nThe LLM proposes an experiment.\nDeterministic policy, broker, provider, watchdog, and measurement components decide whether the experiment is allowed and whether its measured result clears the evaluator.\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\nFPSMaxxing is a Rust 2024 Cargo workspace with OSS governance, a security policy, issue templates, CI, and an organized [documentation index](docs/README.md) covering architecture, plans, threat model, and provider guides.\nEvery stage of the closed loop above has a working implementation on the mock path, except what the walkthrough marks as future.\nWhat ships today, by capability:\n\n- **Capabilities and providers.** Shared capability and provider contracts, a provider SDK lifecycle, and a mock provider covering snapshot, preview, apply, verify, and rollback under test.\n- **Policy and journal.** A control-plane crate holding the capability registry, bounded policy, broker lifecycle, and a durable SQLite experiment journal.\n- **Agent surface.** A stdio MCP gateway that serves the mock path end to end, and a CLI `doctor` command that reports gateway and journal status.\n- **Privileged boundary.** A broker that serves the control plane to authenticated local peers over an IPC boundary, on the Linux-safe path only.\n- **Crash and lease recovery.** An independent watchdog that restores prior state from the journal after a crash or a lease expiry, on the Linux-safe mock path.\n- **Measurement and decision.** A deterministic experiment runner that gates measured trials through an immutable evaluator and replays them from the journal alone.\n\nEverything the walkthrough above states in the future tense is still ahead of us.\nSo are real hardware providers and live frame-time measurement.\n\nTry the read-only alpha:\n\n`` `bash\ncargo test --workspace\ncargo run -p fpsmaxxing-cli -- doctor\ncargo run -p fpsmaxxing-mock-provider\ncargo run -p fpsmaxxing-experiment-runner\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`FPSMAXXING_JOURNAL_PATH` belongs to the unprivileged tools - the gateway, the CLI, and the watchdog - and the privileged broker deliberately does not read it.\n\nRun the watchdog against the same journal to reclaim leaked experiments: `cargo run -p fpsmaxxing-watchdog -- --once` performs a single expired-lease pass and `--recover-all` rolls back every unclosed experiment after a crash.\nIt accepts the same `--journal <path>` and `FPSMAXXING_JOURNAL_PATH` overrides, plus `--interval <seconds>` for its steady-state poll loop.\n\nThe experiment runner measures a baseline and a candidate against a deterministic stand-in for live telemetry, gates the candidate's lifecycle on the immutable evaluator's verdict, journals the trial with its spec, samples, and verdict, then replays it from the journal alone and checks the re-evaluated verdict against the recorded one.\nIt is a demonstration binary rather than an MCP tool, takes no arguments, and journals to an in-memory SQLite database, so it leaves nothing on disk and exits non-zero if a replay diverges from the journal, falls outside the policy gate, or the broker refuses a promoted lifecycle.\n\n### Privileged broker\n\n`fpsmaxxing-broker` is the trusted side of the local IPC boundary: it serves capability discovery and the bounded provider lifecycle to authenticated local peers over a Unix domain socket, and refuses to run on Windows because the Windows named-pipe transport is not yet available.\nThe gateway does not connect to it yet, so the broker path is exercised by the `BrokerClient` in `crates/ipc` and its end-to-end tests in `apps/broker/tests/integration.rs` rather than by the MCP command above.\n[Broker operations and deployment](docs/BROKER_OPERATIONS.md) covers running it directly: socket, journal, and lock paths, private-directory ownership rules, and systemd units.\n\n`` `bash\ncargo run -p fpsmaxxing-broker\ncargo run -p fpsmaxxing-broker -- --help\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.\nA 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.\n\nNot yet on real hardware.\nThe alpha runs capability discovery and the bounded snapshot-to-rollback lifecycle over MCP against a mock provider, and it promotes or rejects one measured experiment through an immutable evaluator that decides from recorded samples and fixed bounds alone.\nReal hardware providers, live frame-time measurement, and a promotion that survives its lease are not implemented yet: the alpha measures a deterministic stand-in for telemetry, and the verdict gates whether a candidate is applied at all rather than whether it persists.\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";
const html = marked.parse(md, {gfm:true, breaks:false});
const el = document.getElementById('out');
el.innerHTML = html;
// convert `` `mermaid fenced blocks (marked renders them as <pre><code class="language-mermaid">)
el.querySelectorAll('pre > code.language-mermaid').forEach(c => {
  const d = document.createElement('div');
  d.className = 'mermaid';
  d.textContent = c.textContent;
  c.parentElement.replaceWith(d);
});
// GitHub alert callouts (> [!IMPORTANT])
el.querySelectorAll('blockquote').forEach(bq => {
  const m = bq.textContent.trimStart().match(/^\[!(NOTE|IMPORTANT|WARNING|TIP|CAUTION)\]/);
  if (!m) return;
  const kind = m[1];
  const colors = {IMPORTANT:'#8250df', NOTE:'#0969da', WARNING:'#9a6700', TIP:'#1a7f37', CAUTION:'#cf222e'};
  bq.style.borderLeftColor = colors[kind];
  bq.style.color = '#1f2328';
  const first = bq.querySelector('p');
  if (first) first.innerHTML = first.innerHTML.replace(/^\[!(\w+)\]\s*(<br>)?/,
    '<strong style="color:'+colors[kind]+'">'+kind.charAt(0)+kind.slice(1).toLowerCase()+'</strong><br>');
});
let tries = 0;
const boot = () => {
  if (!window.__mermaid) { if (tries++ < 100) return setTimeout(boot, 50); }
  window.__mermaid.initialize({startOnLoad:false, theme:'default'});
  window.__mermaid.run({querySelector:'.mermaid'}).then(()=>{document.title='RENDERED';})
    .catch(e=>{document.title='MERMAID-ERROR: '+e.message;});
};
boot();
</script>
</body></html>
- Outcome: ⚠️ 1 info across 1 run (58m7s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 1 info
  • ⚠️ README.md:36 - Line 36 states in the present tense that "The privileged broker applies that adjustment", but line 38 says "today the gateway drives a control plane of its own in process" - so under this README's own convention (line 12: present tense = runs today) the privileged broker is not in that path today. The gateway builds its own in-process ControlPlane (apps/gateway/src/main.rs:15) and never connects to the broker binary. Either make line 36 future tense for the broker hop (as lines 37-38 do for the sidecar and IPC hops) or state up front that the walkthrough describes the target loop with today-corrections attached, since this PR's stated purpose is tense coherence.
  • ℹ️ README.md:97 - "Real hardware providers, live frame-time measurement, and a promotion that survives its lease are the work that remains." reads as the complete gap list, but the walkthrough at lines 37-42 marks three further items as future: the provider-sidecar hop, the gateway-to-broker IPC hop, and the watchdog's safety-violation trigger. Line 87's "apart from the hops the walkthrough marks as future work" hedges this, yet the closing sentence still asserts an exhaustive remainder. Naming the hops here (or saying "plus the hops named above") removes the conflict.
  • ℹ️ README.md:41 - The walkthrough now says only that the evaluator "decides from the recorded measurements whether the candidate is applied at all", so the Mermaid diagram's E -.-&gt;|roll back regression| B edge (line 30) has no prose counterpart in either tense. The previous text covered it ("decides ... whether to keep the change or roll back a regression"). A reader cannot tell whether post-apply regression rollback exists today; one clause marking that edge as future work would close the gap the re-cut opened.
  • ℹ️ README.md:93 - The status bullet says the broker runs "on the Linux-safe path only", while line 124 and docs/BROKER_OPERATIONS.md:8 now say it refuses to run on Windows because the named-pipe transport is missing. The code gates on cfg(unix) (apps/broker/src/main.rs:40), which matches the second phrasing, not the first. "Linux-safe" is a repo-wide shorthand (docs/ARCHITECTURE.md:6, docs/IMPLEMENTATION_PLAN.md:37), so this may be deliberate, but the two sentences make different portability claims 30 lines apart in the same document.

🔧 Fix: fix README broker tense, rollback edge, gap list
3 issues (1 warning, 2 infos) still open:

  • ⚠️ README.md:97 - Line 97 asserts an exhaustive remainder ("... are the work that remains") but names only three of the five items the walkthrough marks as future work. Missing: the watchdog's restore through the broker (line 40), re-measurement under workload inside the lease window (line 42), and the keep-and-iterate edge that drives the next iteration (line 43). Commit e686c3d removed exactly that five-item enumeration from line 87 as a duplicate, and commit 8e04ed4 reconstructed a shorter three-item version here, so the list regressed rather than being restored. Either name all five or drop back to the generic "plus the hops the walkthrough marks as future work".
  • ℹ️ README.md:97 - The closing sentence coordinates two nested lists in one 45-word clause ("Real hardware providers, live frame-time measurement, a promotion that survives its lease, and the provider-sidecar, gateway-to-broker IPC, and watchdog safety-violation hops ..."), and repeats line 87's clause "the hops the walkthrough marks as future work" verbatim ten lines apart. In a PR whose stated purpose is reading as one designed document, splitting this into two sentences (remaining capability work; then the hops, referenced rather than re-listed) removes both the parse burden and the duplication.
  • ℹ️ apps/broker/src/main.rs:100 - docs/ARCHITECTURE.md:56 and docs/BROKER_OPERATIONS.md:36 were updated on this branch to say FPSMAXXING_JOURNAL_PATH belongs to the gateway, CLI, and watchdog, matching apps/watchdog/src/main.rs:111. The JOURNAL_ENV doc comment here still names only "the unprivileged gateway and CLI", so the code rationale now understates who reads that variable. Out of scope for this docs-only branch (no src/ changes allowed); worth a one-line follow-up.

🔧 Fix: drop exhaustive gap list from README status
3 issues (1 warning, 2 infos) still open:

  • ⚠️ README.md:36 - Line 36 now reads "The privileged broker will apply that adjustment across the local IPC boundary" - future tense, which line 12 defines as "what does not exist yet". But line 93 lists "Privileged boundary. A broker that serves the control plane to authenticated local peers over an IPC boundary" under "What ships today, by capability", and the binary is real (apps/broker/src/main.rs, with end-to-end tests in apps/broker/tests/integration.rs). The document now contradicts itself in the opposite direction from round 1: commit 8e04ed4 turned an over-claiming present tense into an under-claiming future tense. Do not flip the tense a third time. The accurate statement is that the broker exists and applies adjustments over IPC today, and that the gateway does not route through it yet - which is exactly what line 126 already says. Rewording line 36 to keep the broker present tense and move the "not yet" onto the gateway hop resolves both directions at once.
  • ℹ️ README.md:58 - Line 58 says in the present tense that the deterministic components "decide whether the experiment is allowed and whether its measured result should be retained". Retention past a lease is marked future on line 43 ("That same verdict will decide whether an improvement persists past its lease") and explicitly not implemented on line 147 ("a promotion that survives its lease [is] not implemented yet ... the verdict gates whether a candidate is applied at all rather than whether it persists"). Line 12 exempts only the design principles and the planned integrations from the tense convention, not the "Why FPSMaxxing?" section, and line 56 immediately above was already converted to future tense on this branch. The clause "whether its measured result should be retained" is the one remaining present-tense claim in that paragraph that describes behavior the code does not have.
  • ℹ️ README.md:125 - README.md:125-132 and docs/BROKER_OPERATIONS.md:6-18 carry the same four facts (trusted side of the IPC boundary, authenticated local peers over a Unix domain socket, refuses to run on Windows for the missing named-pipe transport, gateway not connected so the path runs through BrokerClient and apps/broker/tests/integration.rs) plus the identical two-line cargo run -p fpsmaxxing-broker block. They have already drifted in phrasing: README.md:125 says "refuses to run on Windows because the Windows named-pipe transport is not yet available" while docs/BROKER_OPERATIONS.md:8 says "Only the Unix domain socket transport is implemented, and the Windows named-pipe transport is not yet available, so the binary refuses to run there", and the summary phrase "socket, journal, and lock paths, private-directory ownership rules, and systemd units" now appears in three places (README.md:127, docs/README.md:18, paraphrased at docs/BROKER_OPERATIONS.md:3). Since the stated goal was a README stub plus a link, dropping the duplicated run block and one of the two transport sentences from the README leaves a single owner for each fact.

🔧 Fix: fix README broker tense and evaluator retention claim
2 issues (1 error, 1 info) still open:

  • 🚨 core - Commit 96670f7 committed a 33,767,424-byte binary named core at the repository root alongside a 3-line README edit. Header bytes 7f 45 4c 46 ... 04 00 b7 00 identify it as an ELF core dump (ET_CORE, aarch64), consistent with the out-of-memory kill that ended the prior pipeline run. This branch is docs-only by the author's own constraint (no changes under src/ or crates/), so the file is unintended. It must come out of the branch history rather than be deleted in a follow-up commit: a delete commit leaves the 32MB blob permanently in the pack, so every clone and every CI checkout pays for it. Amend or rebase 96670f7 to drop the path, and add core plus core.* to .gitignore, which currently has no core-dump pattern.
  • ℹ️ README.md:87 - Line 87 scopes its exception to "the hops the walkthrough marks as future work", but two of the walkthrough's future-tense items are not hops: re-measurement under workload inside the lease window (line 42) and a promotion that persists past its lease (line 43). That "hops" wording is a leftover from the five-item enumeration commit e686c3d deleted from this same line, where the list carried the non-hop items explicitly. Round 3 then generalised line 97 to "Everything the walkthrough above states in the future tense is still ahead of us", so the two sentences now scope the same exception differently ten lines apart. Reusing line 97's phrasing on line 87 aligns them without reintroducing any list.

🔧 Fix: drop stray core dump, align README status exception
1 error still open:

  • 🚨 core - The round-4 fix rewrote history on the detached worktree HEAD (now 3e4c075) to drop the 33,767,424-byte ELF core dump, but refs/heads/fm/fpsm-readme-cut-r3 was never moved and still points at 96670f7. git diff 96670f7 3e4c075 is exactly README.md | 2 +- and core | Bin 33767424 -&gt; 0 bytes, and git merge-base --is-ancestor 96670f7 refs/heads/fm/fpsm-readme-cut-r3 still succeeds, so the branch named in this review's own context is the one that carries the blob. Anything that pushes or merges by branch name rather than by the detached HEAD ships the 32MB core dump into remote history permanently, which is the outcome round 4 was fixing. Move the ref to the rewritten tip (git branch -f fm/fpsm-readme-cut-r3 3e4c075) and re-confirm git ls-tree -r --name-only refs/heads/fm/fpsm-readme-cut-r3 | grep -x core is empty before pushing. Per round 4's instruction, do not add .gitignore entries. Note the ref lives in the gate bare repo, so this cannot be corrected from inside this worktree.

🔧 Fix: move branch ref off core-dump commit
1 info still open:

  • ℹ️ README.md:1 - Verification of the round-4/5 fixes, no action needed. The 33,767,424-byte ELF core dump is gone from branch history: git merge-base --is-ancestor 96670f7 refs/heads/fm/fpsm-readme-cut-r3 now exits 1, the branch ref points at 3e4c075, and sweeping all six refs with git ls-tree -r --name-only finds no core path, so the blob is unreachable and will not be pushed. The worktree is clean and the diff against 9e76b27 is 4 files, docs only.
⚠️ **Test** - 1 info
  • ℹ️ core - The stated target commit 96670f7 contains a 33 MB core dump at the repo root. The worktree HEAD (3e4c075, a sibling of 96670f7 off the same parent) already drops it and carries one extra prose fix, so the checked-out change is docs-only and clean. Flagging only so the reviewer confirms the branch tip being pushed is 3e4c075 and not 96670f7. Chromium crashed the same way during my screenshot capture and dropped a 346 MB core into the worktree; I deleted it and the tree is clean.
  • cargo test --workspace --locked (170 passed, 0 failed; needed CC/AR zig shims for libsqlite3-sys, a known environment quirk unrelated to the change)
  • Rendered README.md before/after, docs/BROKER_OPERATIONS.md and docs/README.md to GitHub-styled HTML with Mermaid and captured full-page screenshots via headless Chromium over CDP
  • git diff --name-only 9e76b27..3e4c075 - confirmed 4 docs files, 0 under src/ or crates/
  • grep -c &#39;—&#39; on README.md, docs/BROKER_OPERATIONS.md, docs/README.md - 0 em dashes each
  • diff &lt;(git show 9e76b27:README.md | awk &#39;/^```mermaid/,/^```$/&#39;) &lt;(awk &#39;/^```mermaid/,/^```$/&#39; README.md) - closed-loop diagram byte-identical
  • Relocation completeness sweep: grepped each named reference topic in docs/BROKER_OPERATIONS.md and confirmed 0 remaining hits in README.md
  • Relative-link resolver over the three touched docs - 23 links checked, 0 broken
  • cargo run -p fpsmaxxing-cli -- doctor and cargo run -p fpsmaxxing-experiment-runner - README quickstart commands
  • printf &#39;{&#34;jsonrpc&#34;:&#34;2.0&#34;,...tools/list...}&#39; ... | cargo run -p fpsmaxxing-gateway then re-ran doctor and read the SQLite journal (8 lifecycle rows)
  • FPSMAXXING_JOURNAL_PATH=... cargo run -p fpsmaxxing-watchdog -- --once vs cargo run -p fpsmaxxing-broker -- --help - proves the corrected env-var ownership sentence
  • Verified changed factual claims against code: apps/watchdog/src/main.rs:111, apps/broker/src/main.rs:43, absence of BrokerClient in apps/gateway/src
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

undeemed added 10 commits July 28, 2026 19:22
…tions

The README had accreted one section per merged workstream, each in its own
register, and was never re-cut as a whole. Five defects addressed:

- The broker section was ~48 lines of filesystem-permission reference on one
  component. Relocated in full to docs/BROKER_OPERATIONS.md, registered in the
  docs index under a new Operations section, and reduced to 9 lines in the
  README: what the broker is, that it is Linux-only, that the gateway does not
  connect to it yet, a two-line run command, and a link.
- The narrative described the watchdog and the measurement loop in the future
  tense while the status list described them in the present. The alpha caveat
  now carries the "not on real hardware" weight once, prominently, and states
  the tense convention; the walkthrough is present tense throughout.
- The same loop was drawn four times. Kept the Mermaid diagram and the prose
  walkthrough; dropped the observe/propose/validate text block and the ASCII
  architecture section, which the Mermaid already renders better.
- Repository status was a 13-bullet merge-history changelog. Reorganised into
  six bullets by capability.
- The first FAQ answer was a five-sentence wall. Split into the direct answer
  followed by the caveat.

No behavioral change. The closed-loop section, its heading, intro, and Mermaid
diagram are byte-identical apart from the three tense fixes above.
@undeemed
undeemed merged commit 33dbfe3 into main Jul 29, 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