Skip to content

docs: re-cut README and relocate broker operations reference - #16

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

docs: re-cut README and relocate broker operations reference#16
undeemed merged 7 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: (1) the ~48-line 'Privileged broker' section was 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 forbidden. (2) Tense was incoherent between the walkthrough and the status list; convention is now 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. (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. (5) The first FAQ answer was a five-sentence wall and now leads with the direct answer then the caveat. HARD CONSTRAINT, captain-set and machine-verified by 'git diff --name-only origin/main...HEAD': this branch touches documentation only. No file under any src/ directory and no file under crates/ may change, including doc comments. The previous run's review round edited apps/broker/src/main.rs doc comments and commit 4ae6b8d reverts exactly that; do not re-apply it. The stale JOURNAL_ENV doc comment in apps/broker/src/main.rs is a known, deliberate out-of-scope follow-up, not a defect of this branch. Also protected by direct captain order: the '## The closed loop' section and its Mermaid diagram must stay near the top, byte-identical to origin/main. Repo Markdown convention is one full sentence per line and plain dashes only; README must contain zero em dashes. Everything else on this branch already cleared a full review, test, document, lint, push, PR, and CI cycle as PR #15.

What Changed

  • Rewrote README.md as a single document: the closed-loop walkthrough and status list now use present tense only for what runs on the mock path and explicit future tense for what does not, the redundant arrow-text pipeline and ASCII architecture diagram are cut (the Mermaid diagram is byte-identical to main), "Repository status" is regrouped by capability instead of merge history, and the first FAQ answer leads with the direct answer before the alpha caveat. Corrected FPSMAXXING_JOURNAL_PATH ownership to gateway, CLI, and watchdog, and narrowed the broker's platform refusal to Windows.
  • Moved the broker's filesystem-permission reference material out of the ~48-line README section into a new docs/BROKER_OPERATIONS.md (socket/journal/lock paths, private-directory ownership and mode rules, why /tmp and /run are refused, XDG_RUNTIME_DIR versus the single-instance lock, systemd RuntimeDirectory settings, flag/env precedence). The README keeps a short broker section plus a link; the page is registered in the docs/README.md index and linked from docs/ARCHITECTURE.md.
  • Added core and core.* to .gitignore after a 19 MB crash dump was accidentally committed and removed earlier on this branch.

Documentation-only apart from the .gitignore line; no file under crates/ or any src/ directory changed, and commit 4ae6b8d reverts an earlier run's broker doc-comment edit to keep that constraint. The stale JOURNAL_ENV doc comment in apps/broker/src/main.rs:100 is a known out-of-scope follow-up.

Risk Assessment

✅ Low: Docs-only change with the accidental core dump purged from history; every relocated permission, ownership, and lifecycle claim now checks out against apps/broker, apps/watchdog, and apps/experiment-runner, leaving only two cosmetic redundancy items.

Testing

Rendered the README before and after to GitHub-styled HTML and captured screenshots showing all five defects fixed: the 49-line broker section is down to 11 with its reference material relocated intact to a new docs/BROKER_OPERATIONS.md, the alpha caveat now leads once up front with present/future tense split consistently, only one Mermaid pipeline drawing remains, "Repository status" is grouped by capability, and the first FAQ answer opens with "Not yet on real hardware." before the caveat. Drove the new README -> broker-ops -> back-to-anchor link path in a real browser with no console errors, and machine-checked the hard constraints: docs-only diff, apps/broker/src/main.rs byte-identical to origin/main, the closed-loop Mermaid block byte-identical by md5, zero em dashes. Then built the workspace with local zig shims and ran the README's own documented commands, which confirms its present-tense claims: doctor flips from journal missing to ready, the MCP snippet returns a verified and rolled-back lifecycle, the experiment runner promotes and replays consistently, the watchdog passes both exit 0, and the broker enforces every ownership, sticky-bit, traversal, single-instance and env-var rule the relocated page documents. cargo test --workspace is fully green. No product failures; the only leftovers are an untracked pre-existing core dump and seven multi-sentence README lines inherited unchanged from origin/main.

  • Evidence: README re-cut: before/after by defect (the main reviewer artifact - all five defects side by side, rendered) (local file: /tmp/no-mistakes-evidence/01KYNK9V5JXXXHP3HPSBH74FJT/00-readme-recut-before-after-by-defect.png)
  • Evidence: README.md rendered - BEFORE (origin/main 9e76b27), full page, 12884px tall (local file: /tmp/no-mistakes-evidence/01KYNK9V5JXXXHP3HPSBH74FJT/01-readme-BEFORE-full.png)
  • Evidence: README.md rendered - AFTER (93f43c6), full page, 10456px tall (19% shorter) (local file: /tmp/no-mistakes-evidence/01KYNK9V5JXXXHP3HPSBH74FJT/02-readme-AFTER-full.png)
  • Evidence: docs/BROKER_OPERATIONS.md rendered - the new page holding all relocated reference material (local file: /tmp/no-mistakes-evidence/01KYNK9V5JXXXHP3HPSBH74FJT/03-BROKER_OPERATIONS-new-page.png)
  • Evidence: docs/README.md rendered - new Operations section registering the broker ops page in the index (local file: /tmp/no-mistakes-evidence/01KYNK9V5JXXXHP3HPSBH74FJT/04-docs-index-operations-row.png)
  • Evidence: Navigation step 1 - README at #privileged-broker, trimmed to 3 prose lines plus the run snippet (local file: /tmp/no-mistakes-evidence/01KYNK9V5JXXXHP3HPSBH74FJT/05-nav-step1-README-privileged-broker.png)
  • Evidence: Navigation step 2 - clicking the link lands on Broker operations and deployment (local file: /tmp/no-mistakes-evidence/01KYNK9V5JXXXHP3HPSBH74FJT/06-nav-step2-BROKER_OPERATIONS-top.png)
  • Evidence: Navigation step 3 - the backlink returns to README#privileged-broker, anchor highlighted at viewport top (local file: /tmp/no-mistakes-evidence/01KYNK9V5JXXXHP3HPSBH74FJT/07-nav-step3-backlink-lands-on-anchor.png)
Evidence: CLI transcript - the README's documented commands run verbatim

$ cargo run -p fpsmaxxing-cli -- doctor FPSMaxxing diagnostics contracts: ready provider SDK: ready gateway: MCP mock path available journal: missing (no experiments journaled yet) (/tmp/tmp.xPgTc7whOC/journal.sqlite) hardware writes: disabled status: read-only alpha mock path ready $ printf ... | cargo run -p fpsmaxxing-gateway # README MCP snippet {"id":1,"jsonrpc":"2.0","result":{"tools":[ {"name":"fpsmaxxing.capabilities", "description":"Discover typed, policy-approved capabilities"}, {"name":"fpsmaxxing.run_mock_lifecycle", "description":"Run snapshot, preview, apply, verify, and rollback for mock.value"}]}} {"id":2,"jsonrpc":"2.0","result":{"content":[{"type":"text", "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 lifecycle ran journal: ready (/tmp/tmp.xPgTc7whOC/journal.sqlite) $ cargo run -p fpsmaxxing-experiment-runner trial 1 -> Promote (Promoted); fps_improvement = 30.0 lifecycle: provider mock, verified = true, rolled_back = true replay 1 -> recomputed Promote; consistent with journal = true, policy legal = true exit=0 $ cargo run -p fpsmaxxing-watchdog -- --once exit=0 $ cargo run -p fpsmaxxing-watchdog -- --recover-all exit=0

### Running the commands the README documents, verbatim, against a scratch journal
### FPSMAXXING_JOURNAL_PATH=/tmp/tmp.xPgTc7whOC/journal.sqlite

$ cargo run -p fpsmaxxing-cli -- doctor
FPSMaxxing diagnostics
  contracts: ready
  provider SDK: ready
  gateway: MCP mock path available
  journal: missing (no experiments journaled yet) (/tmp/tmp.xPgTc7whOC/journal.sqlite)
  hardware writes: disabled
  status: read-only alpha mock path ready

$ printf ... | cargo run -p fpsmaxxing-gateway    # README MCP snippet
{
  "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 lifecycle ran
FPSMaxxing diagnostics
  contracts: ready
  provider SDK: ready
  gateway: MCP mock path available
  journal: ready (/tmp/tmp.xPgTc7whOC/journal.sqlite)
  hardware writes: disabled
  status: read-only alpha mock path ready

$ cargo run -p fpsmaxxing-experiment-runner    # README: "measures a baseline and a candidate ... then replays it from the journal alone"
trial 1 -> Promote (Promoted); fps_improvement = 30.0
  lifecycle: provider mock, verified = true, rolled_back = true
replay 1 -> recomputed Promote; consistent with journal = true, policy legal = true
exit=0

$ cargo run -p fpsmaxxing-watchdog -- --once   # README: "performs a single expired-lease pass"
exit=0

$ cargo run -p fpsmaxxing-watchdog -- --recover-all   # README: "rolls back every unclosed experiment after a crash"
exit=0
Evidence: Every claim relocated into docs/BROKER_OPERATIONS.md, checked against the running broker binary

=== 2. "RuntimeDirectoryMode defaults to 0755 ... a unit that omits the mode is refused on every start" === $ XDG_RUNTIME_DIR=/tmp/tmp.jGy8fIS7KW # private dir pre-created 0755, exactly what systemd does by default exit=1 :: fpsmaxxing-broker: /tmp/tmp.jGy8fIS7KW/fpsmaxxing must be a directory owned by uid 10001 with mode 700 $ chmod 0700 $XDG_RUNTIME_DIR/fpsmaxxing && rerun exit=124 (still serving when the 3s timeout fired) :: listening on .../fpsmaxxing/broker.sock (same-uid ACL, uid 10001) === 3. "a shared root like /tmp is refused" === exit=1 :: fpsmaxxing-broker: /tmp must be a directory owned by uid 10001 or root that no other user can reach it === 4. "a merely traversable directory like /run ... is refused too" === exit=1 :: fpsmaxxing-broker: /run must be a directory owned by uid 10001 or root that no other user can reach it === 5. "Only one broker may run per user ... a second broker exits non-zero" === second broker exit=1 :: broker.lock is held by a running broker; only one may own this machine's knobs === 6. "the lock is not derived from --socket or --journal" === second broker, different --socket and --journal: exit=1 :: broker.lock is held by a running broker === 7. "the privileged broker deliberately does not read FPSMAXXING_JOURNAL_PATH" === journal the broker actually wrote: /tmp/tmp.jGy8fIS7KW/fpsmaxxing/journal.sqlite path from FPSMAXXING_JOURNAL_PATH exists? no - broker ignored it, as documented

### docs/BROKER_OPERATIONS.md - each relocated claim checked against the real fpsmaxxing-broker binary
### (uid 10001, branch fm/fpsm-readme-cut-r3 @ 93f43c6)

=== 1. "Running the broker": cargo run -p fpsmaxxing-broker -- --help ===
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

A flag wins over its environment variable. Unset, each falls back into the
broker's own owner-only directory under $XDG_RUNTIME_DIR (or /run when it is
unset, is not absolute, or the broker runs as root); that directory is
established either way, because the lock that admits one broker per uid lives
in it. Every path must be absolute and sit in an existing directory owned by
the broker or root that no other user can reach (mode 0700), itself under a
chain of directories owned by the broker or root that no other user can write,
or the broker refuses to start.

=== 2. "RuntimeDirectoryMode defaults to 0755 ... a unit that omits the mode is refused on every start" ===
$ XDG_RUNTIME_DIR=/tmp/tmp.jGy8fIS7KW   # private dir pre-created 0755, exactly what systemd does by default
exit=1 :: fpsmaxxing-broker: /tmp/tmp.jGy8fIS7KW/fpsmaxxing must be a directory owned by uid 10001 with mode 700
$ chmod 0700 $XDG_RUNTIME_DIR/fpsmaxxing && rerun
exit=124 (124 = still serving when the 3s timeout fired) :: fpsmaxxing-broker: listening on /tmp/tmp.jGy8fIS7KW/fpsmaxxing/broker.sock (same-uid ACL, uid 10001)

=== 3. "a shared root like /tmp is refused" (sticky bit does not excuse group/world write) ===
$ --socket /tmp/fpsm-demo.sock   # /tmp is 1777
exit=1 :: fpsmaxxing-broker: /tmp must be a directory owned by uid 10001 or root that no other user can reach it

=== 4. "a merely traversable directory like /run ... is refused too" ===
$ --socket /run/fpsm-demo.sock   # /run is 0755 root, traversable by all
exit=1 :: fpsmaxxing-broker: /run must be a directory owned by uid 10001 or root that no other user can reach it

=== 5. "Only one broker may run per user ... a second broker exits non-zero" ===
first broker: fpsmaxxing-broker: listening on /tmp/tmp.jGy8fIS7KW/fpsmaxxing/broker.sock (same-uid ACL, uid 10001)
second broker exit=1 :: fpsmaxxing-broker: /tmp/tmp.jGy8fIS7KW/fpsmaxxing/broker.lock is held by a running broker; only one may own this machine's knobs

=== 6. "the lock is not derived from --socket or --journal, so neither buys a second instance" ===
second broker, different --socket and --journal: exit=1 :: fpsmaxxing-broker: /tmp/tmp.jGy8fIS7KW/fpsmaxxing/broker.lock is held by a running broker; only one may own this machine's knobs

=== 7. README: "FPSMAXXING_JOURNAL_PATH belongs to the unprivileged tools ... the privileged broker deliberately does not read it" ===
exit=124 :: fpsmaxxing-broker: listening on /tmp/tmp.jGy8fIS7KW/fpsmaxxing/broker.sock (same-uid ACL, uid 10001)
journal the broker actually wrote: /tmp/tmp.jGy8fIS7KW/fpsmaxxing/journal.sqlite 
path from FPSMAXXING_JOURNAL_PATH exists? no - broker ignored it, as documented
Evidence: Hard-constraints check (docs-only, Mermaid byte-identity, em dashes, sentence-per-line, relocation size, link resolution)

--- C1: documentation only --- README.md / docs/ARCHITECTURE.md / docs/BROKER_OPERATIONS.md / docs/README.md verdict: PASS - no file under any src/ or crates/ directory changed --- C1b: the 4ae6b8d revert was not re-applied --- apps/broker/src/main.rs vs origin/main: PASS - byte-identical stale JOURNAL_ENV doc comment: yes, untouched as required --- C2: closed-loop Mermaid byte-identical --- e311e9ff1b60e526b9166c96fa855cf1 origin/main e311e9ff1b60e526b9166c96fa855cf1 HEAD first H2 is 15:## The closed loop --- C3: em dashes --- README.md: 0 docs/BROKER_OPERATIONS.md: 0 --- C5: relocation preserved, not deleted --- origin/main README broker section: 49 lines HEAD README broker section: 11 lines (3 prose, one of which is the link) docs/BROKER_OPERATIONS.md (new): 66 lines --- C6: pipeline drawn once --- mermaid blocks in README: 1 ASCII "## Architecture" block: removed "observe -> propose -> ..." arrow block: removed

### Hard constraints for branch fm/fpsm-readme-cut-r3 (9e76b27 -> 93f43c6)

--- C1: documentation only. "git diff --name-only origin/main...HEAD" ---
    README.md
    docs/ARCHITECTURE.md
    docs/BROKER_OPERATIONS.md
    docs/README.md
    verdict: PASS - no file under any src/ or crates/ directory changed

--- C1b: the 4ae6b8d revert of apps/broker/src/main.rs doc comments was not re-applied ---
    apps/broker/src/main.rs vs origin/main: PASS - byte-identical
    stale JOURNAL_ENV doc comment still present (known out-of-scope follow-up): yes, untouched as required

--- C2: "## The closed loop" Mermaid diagram byte-identical to origin/main ---
e311e9ff1b60e526b9166c96fa855cf1  origin/main README mermaid block
e311e9ff1b60e526b9166c96fa855cf1  HEAD        README mermaid block
    section position: first H2 is 15:## The closed loop

--- C3: zero em dashes in README (repo convention: plain dashes only) ---
    README.md em dashes: 0
    docs/BROKER_OPERATIONS.md em dashes: 0

--- C4: one full sentence per line, on the lines this branch changed ---
    docs/BROKER_OPERATIONS.md (new file): 0 multi-sentence lines
    README.md: 7 multi-sentence lines remain, all byte-identical to origin/main
                (L136 Documentation, L151/155/159/163 FAQ answers 2-5, L167 Contributing, L171 Security)
                pre-existing, untouched by this branch

--- C5: relocation preserved the reference material rather than deleting it ---
    origin/main README '### Privileged broker' section: 49 lines
    HEAD       README '### Privileged broker' section: 11 lines (3 prose lines, one of which is the link)
    docs/BROKER_OPERATIONS.md (new):                    66 lines
    every fact from the old section re-verified against the running binary in 09-broker-operations-claims-transcript.txt

--- C6: pipeline is drawn once, not four times ---
    mermaid blocks in README: 1
    ASCII "## Architecture" pipeline block: removed
    "observe -> propose -> ..." arrow text block: removed

--- C7: every relative link and heading anchor in the touched docs resolves ---
    checked README.md, docs/README.md, docs/BROKER_OPERATIONS.md, docs/ARCHITECTURE.md: all resolve
    round trip exercised in a browser: README#privileged-broker -> docs/BROKER_OPERATIONS.md -> back to README#privileged-broker
    (screenshots 05/06/07; the backlink lands with the anchor exactly at the top of the viewport)
- Outcome: ⚠️ 2 infos across 1 run (23m50s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 2 infos
  • ⚠️ docs/BROKER_OPERATIONS.md:9 - The "gateway does not reach the broker yet" status now lives in four places: README.md:10 (IMPORTANT block), README.md:37 (walkthrough), README.md:126 (broker section), and docs/BROKER_OPERATIONS.md:9. The point of the re-cut is one coherent document; four copies of the same volatile status line will drift the moment the gateway is wired to the broker, and BROKER_OPERATIONS.md:9 also duplicates README.md:126 nearly verbatim including the apps/broker/tests/integration.rs path. Suggest stating it once (walkthrough) and having the broker section plus BROKER_OPERATIONS defer to it.
  • ℹ️ docs/README.md:18 - README.md:127 and docs/README.md:18 both advertise the new page as covering "systemd units", but docs/BROKER_OPERATIONS.md contains exactly one systemd sentence (line 58: RuntimeDirectory + RuntimeDirectoryMode) and no unit file or unit-level guidance. Either reword both link descriptions to "systemd RuntimeDirectory requirements" or add a minimal example unit.
  • ℹ️ README.md:93 - README.md:93 says the broker is "on the Linux-safe path only" while README.md:125 (correctly, matching the cfg(not(unix)) gate at apps/broker/src/main.rs:40) says it refuses only on Windows. The base README had no platform qualifier on this bullet, so the new wording introduces the tension; a reader can conclude the binary refuses on macOS/BSD when it does not. "Linux-safe" is existing repo vocabulary (docs/ARCHITECTURE.md:6), so this is only about the two statements sitting in the same document.
  • ℹ️ README.md:38 - "today that in-process control plane links its provider directly" grammatically refers to the gateway's in-process plane from line 37, which leaves the impression the broker already reaches a sidecar when driven by BrokerClient. It does not: apps/broker/src/main.rs:215-217 boxes MockProvider straight into its own ControlPlane. Consider "today both the gateway's and the broker's control planes link their provider directly."

🔧 Fix: defer broker doc status to README, fix systemd wording
2 infos still open:

  • ℹ️ README.md:87 - README:87 and README:97 both hang a load-bearing status claim on "the walkthrough" ("except what the walkthrough marks as future", "Everything the walkthrough above states in the future tense"), but no section in the README is ever labelled a walkthrough. The intended referent is the prose at README:34-43 under "## The closed loop". Since line 87 is the one sentence that bounds how much of the closed loop actually works, a reader who cannot resolve the term cannot check the claim. Naming it explicitly ("except what the closed-loop walkthrough above marks as future") closes it without touching the protected diagram or section.
  • ℹ️ docs/BROKER_OPERATIONS.md:33 - The new page's central term is introduced after it is used. &lt;private dir&gt; appears in the defaults column at lines 33-34, and "the default private directory already is one" at line 39, but "## The private directory" does not define it ($XDG_RUNTIME_DIR/fpsmaxxing, or /run/fpsmaxxing under root) until line 49. In the old README section the private-directory prose preceded the table, so the order was correct; the relocation reversed it. Moving "## The private directory" ahead of "## Socket and journal paths" restores the reading order with no wording change.

🔧 Fix: name walkthrough referent, reorder broker ops sections
3 issues (1 warning, 2 infos) still open:

  • ⚠️ docs/BROKER_OPERATIONS.md:51 - "held to the same bar as the default" is new on this branch (the base README said only "held to the same bar") and the added comparison is wrong on the ownership axis. In apps/broker/src/main.rs, vet_directory accepts a parent whose owner is metadata.uid() == broker_uid || metadata.uid() == ROOT_UID, while private_directory_in accepts the private directory only when metadata.uid() == broker_uid. Line 36 of this same page states that distinction explicitly ("root ownership satisfies an explicit --socket or --journal parent, but a broker accepts its private directory only when it owns that itself"), so the page now contradicts itself 15 lines apart on a security check. Mode and ancestor bars do match; only ownership differs. Dropping "as the default" restores the accurate base wording.
  • ℹ️ docs/BROKER_OPERATIONS.md:33 - After the round-2 reorder, lines 31-33 are three consecutive sentences carrying the same fact. Line 31 defines the private directory as $XDG_RUNTIME_DIR/fpsmaxxing or /run/fpsmaxxing; line 32 says the broker creates it "whether or not an override moved the socket and the journal out of it, because the single-instance lock lives there"; line 33 then repeats both ("still establishes that directory even when both paths are given", and re-spells the same two paths). In the base README these two sentences sat on opposite sides of the settings table, so the repetition was not visible; the relocation made them adjacent. Line 33 adds only "on every start" and can fold into line 32.
  • ℹ️ README.md:12 - The new caveat asserts a universal convention - "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" - and carves out only the design principles and the planned integrations. The FAQ is not carved out and violates it: README.md:151 reads "Planned GPU operations use supported vendor APIs, query device limits first, require rollback, and run under an independent thermal watchdog" and "Persistent or high-risk operations require explicit approval", both present tense for capabilities that do not exist (no GPU provider, no approval flow in the workspace). Since defect 2 of this re-cut was tense coherence, either extend the carve-out to name the FAQ or shift those two sentences to future tense.

🔧 Fix: fix broker directory ownership claim, cut duplicate sentence
2 issues (1 error, 1 warning) still open:

  • 🚨 core:1 - Commit 2838ed3 committed a 19,824,640-byte ELF core dump (core) at the repository root alongside its 3-line docs edit. Confirmed: ELF e_type == 4 (ET_CORE), and embedded strings identify it as a crash of /home/fleet/.local/libexec/sentrux check . (the Stop-hook quality gate), not project code. Three problems: (1) it breaks the branch's docs-only constraint - git diff --name-only 9e76b27..HEAD lists core next to the four Markdown files; (2) once merged the 19 MB blob is in history permanently and cannot be removed without a rewrite, and every future clone pays for it; (3) a core dump is a snapshot of process memory, so it can contain repository file contents, environment variables, and any token sentrux had loaded - publishing it to a shared remote is an unintended disclosure. Fix: drop the blob from the commit rather than deleting it in a follow-up commit (git rm --cached core &amp;&amp; rm core, then amend 2838ed3 so the blob never enters history), and add core plus core.* to .gitignore, which currently has no coredump pattern.
  • ⚠️ docs/BROKER_OPERATIONS.md:32 - Line 32 says the broker "refuses to start unless it and every directory above it are owned by the broker or root and are not writable by anyone else", where "it" is the private directory. That is wrong for the private directory on both axes, and the page contradicts itself on the same security check within twenty lines. Ownership: private_directory_in (apps/broker/src/main.rs:508-511) accepts the directory only when metadata.uid() == broker_uid, so a root-owned /run/fpsmaxxing is refused for a non-root broker - exactly what line 35 and the round-3 rewrite at line 51 both state. Mode: the same check requires metadata.mode() &amp; 0o777 == PRIVATE_DIR_MODE (exact 0700, so no other-user read or traverse either), which is stricter than "not writable by anyone else"; only the ancestors get the Bar::NoForeignWrite bar that sentence describes. The wording is inherited from the base README, but there the correcting sentence sat on the far side of the settings table; the round-2 reorder put the two three lines apart. Narrowing line 32's clause to the ancestors and letting line 35 keep the private-directory rule resolves it without touching the code.

🔧 Fix: drop committed core dump, fix private-directory ownership rule
2 infos still open:

  • ℹ️ README.md:97 - README:87 ("Every stage of the closed loop above has a working implementation on the mock path, except what the closed-loop walkthrough above marks as future") and README:97 ("Everything the closed-loop walkthrough above states in the future tense is still ahead of us") are the same claim stated twice, inverted, ten lines apart with only the capability list between them. Line 98 ("So are real hardware providers and live frame-time measurement") is the only new information in that closing pair, and it depends on line 97 for its "So are". Since the point of the re-cut was one designed document rather than accreted statements, folding 97 into 98 ("Real hardware providers and live frame-time measurement are also still ahead of us") keeps the new fact and drops the restatement.
  • ℹ️ .gitignore:1 - The 19 MB core dump was correctly removed from branch history, but .gitignore still carries no core / core.* pattern, so the next sentrux Stop-hook crash drops another dump at the repo root where a git add -A picks it up again. Adding the pattern would put a non-Markdown file in the diff and break this branch's machine-verified docs-only constraint, so it is a deliberate tradeoff rather than an oversight; worth a one-line follow-up commit on main instead.
⚠️ **Test** - 2 infos
  • ℹ️ core - An untracked 19 MB core dump sits at the repo root. It predates this test run (it was already in git status at session start) and it is not in the target commit, but it is also not covered by .gitignore, so a future git add -A would re-commit it - which is exactly what commit 93f43c6 had to undo. Removing it is a deletion, so I left it in place rather than deciding for you.
  • ℹ️ README.md:136 - Seven README lines still carry more than one sentence, against the repo's one-sentence-per-line convention: L136 (Documentation), L151/L155/L159/L163 (FAQ answers 2-5), L167 (Contributing), L171 (Security). All seven are byte-identical to origin/main and untouched by this branch, so they are pre-existing and out of its scope. Noting them only so the convention gap is not mistaken for something this branch introduced.
  • git diff --name-only 9e76b27..HEAD - confirmed only README.md, docs/ARCHITECTURE.md, docs/BROKER_OPERATIONS.md, docs/README.md changed; grep for (^|/)(src|crates)/ returns nothing
  • git diff --quiet 9e76b27..HEAD -- apps/broker/src/main.rs - byte-identical, so the 4ae6b8d revert was not re-applied; grep JOURNAL_ENV apps/broker/src/main.rs confirms the known stale doc comment is untouched
  • awk &#39;/^```mermaid/,/^```$/&#39; README.md | md5sum compared against the same extraction from git show 9e76b27:README.md - both e311e9ff1b60e526b9166c96fa855cf1
  • grep -c &#39;—&#39; README.md docs/BROKER_OPERATIONS.md - zero em dashes in both
  • Python link/anchor walker over README.md, docs/README.md, docs/BROKER_OPERATIONS.md, docs/ARCHITECTURE.md - every relative file target and every #fragment resolves to a real heading
  • Rendered README.md at 9e76b27 and at HEAD, plus docs/BROKER_OPERATIONS.md and docs/README.md, to GitHub-styled HTML (marked + github-markdown-css + mermaid 11) and captured full-page screenshots with headless Chromium
  • Composed and screenshotted a five-row before/after comparison page, one row per stated defect
  • Browser-driven navigation: load README, scroll to #privileged-broker, click "Broker operations and deployment", assert h1 is "Broker operations and deployment", click the backlink, assert URL is README.html#privileged-broker and the anchor sits at offset 0px; zero console errors
  • cargo build -p fpsmaxxing-gateway -p fpsmaxxing-cli -p fpsmaxxing-broker -p fpsmaxxing-watchdog -p fpsmaxxing-experiment-runner with local zig CC/AR shims to work around the libsqlite3-sys build-script failure
  • cargo run -p fpsmaxxing-cli -- doctor before and after the lifecycle - journal reported missing then ready
  • The README's MCP snippet verbatim: printf &#39;%s\n&#39; &#39;{...tools/list...}&#39; &#39;{...tools/call fpsmaxxing.run_mock_lifecycle...}&#39; | cargo run -p fpsmaxxing-gateway
  • cargo run -p fpsmaxxing-experiment-runner - promoted trial with consistent replay, exit 0
  • cargo run -p fpsmaxxing-watchdog -- --once and -- --recover-all - both exit 0
  • fpsmaxxing-broker --help, plus refusal cases for a 0755 private directory, --socket /tmp/..., --socket /run/..., a second concurrent broker, a second broker with different --socket/--journal, and FPSMAXXING_JOURNAL_PATH being ignored
  • cargo test --workspace - 170 tests across 20 targets, all passing, including apps/broker/tests/integration.rs which the README now names
⚠️ **Document** - 1 warning
  • ⚠️ apps/broker/src/main.rs:100 - apps/broker/src/main.rs still documents FPSMAXXING_JOURNAL_PATH as belonging to "the unprivileged gateway and CLI" (JOURNAL_ENV doc comment at :100-104, resolve_paths_from doc comment at :262, test constant doc at :695), but apps/watchdog/src/main.rs:111 reads that variable too. README.md:115 and docs/ARCHITECTURE.md:56 were both corrected to "gateway, CLI, and watchdog" on this branch; the code doc comments were not. Left unfixed deliberately: this branch is under a machine-verified docs-only scope constraint (git diff --name-only must touch no file under crates/ or any src/), and commit 4ae6b8d reverts exactly this edit from a prior run. Needs a human call on whether to land it as a separate non-docs PR.
🔧 **Lint** - 1 issue found → auto-fixed ✅
  • 🚨 core - A 19,804,160-byte aarch64 ELF core dump is committed at the repository root, added by target commit 80942ec (Bin 0 -&gt; 19804160 bytes) and currently tracked by git. It is unrelated build/crash debris on a branch whose stated constraint is documentation-only, it bloats every clone, and .gitignore has no core pattern so it can be re-added. Commit 93f43c6 two commits earlier is titled "drop committed core dump", so the removal intent is already established. Fix: git rm --cached core &amp;&amp; rm core, then append core and core.* to .gitignore. Not auto-applied: deleting a tracked file is destructive, and adding a .gitignore entry is a non-documentation change on a docs-only branch, so both need author sign-off.

🔧 Fix: drop core dump from history, ignore future dumps
✅ Re-checked - no issues remain.

✅ **Push** - passed

✅ No issues found.

undeemed added 7 commits July 29, 2026 00:09
A review fix round edited doc comments in apps/broker/src/main.rs to match
the docs updated on this branch. The branch is docs-only by explicit
constraint, so no file under a src/ directory may change here. The stale
comment stands as a separate follow-up.
@undeemed
undeemed merged commit 3f9a580 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