Skip to content

fix(I10): reduce polling lag, fix sidebar overflow, layout fixes - #110

Merged
Ghenghis merged 1 commit into
feat/hermes3d-7-complete-gui-repo-wiringfrom
claude24/i10-perf-shell
May 9, 2026
Merged

Ghenghis merged 1 commit into
feat/hermes3d-7-complete-gui-repo-wiringfrom
claude24/i10-perf-shell

Conversation

@Ghenghis

@Ghenghis Ghenghis commented May 8, 2026 •

Copy link
Copy Markdown
Owner

Task

Task: H3D-CLAUDE24-I10-PERF-SHELL
Hermes evidence chain: PASS

Summary

  • AppShell: Removed lg:overflow-hidden from <main> in dashboard mode — on large viewports this hard-clipped panel content; overflow-auto is now consistent for all screen sizes
  • Sidebar: Wrapped <AgentChatMirror /> in a min-h-0 shrink overflow-hidden div so the chat panel (which has shrink-0 on its own root element) can no longer displace nav items off-screen when expanded to tall mode
  • TopBar: Stale data fix — was fetch-on-mount only (0 ms interval, effectively never refreshed); added setInterval(fetchAll, 10_000) to refresh system snapshot, notifications, and proof bundle every 10 s; timer is cleared on unmount

Polling changes

Component Old interval New interval Notes
TopBar (system snapshot) never (mount-only) 10 000 ms Non-critical status display
TopBar (notifications) never (mount-only) 10 000 ms Piggybacks same timer
TopBar (proof bundle) never (mount-only) 10 000 ms Piggybacks same timer

No polling was decreased below 3 000 ms. No WebSocket or streaming connections were modified.

Layout fixes applied

  1. AppShell <main> overflow — lg:overflow-hidden removed; dashboard mode now uses overflow-auto on all viewports, preventing panel cutoff on screens ≥ 1024 px wide
  2. Sidebar AgentChatMirror overflow — added min-h-0 shrink overflow-hidden wrapper so chat panel shrinks within the sidebar flex column instead of overflowing and hiding nav items

Lint result

node_modules not present in worktree — lint skipped per task instructions.

Files changed (locked set only)

  • 03_implementation/ui/src/app/AppShell.tsx
  • 03_implementation/ui/src/components/layout/Sidebar.tsx
  • 03_implementation/ui/src/components/layout/TopBar.tsx
  • 03_implementation/ui/src/styles/globals.css — no changes needed (13 px base font and dashboard-grid overflow:hidden are intentional)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Added comprehensive safety and quality specifications for UI rendering, data handling, and system operations.
    • Expanded configuration documentation and operational guidelines.
  • Chores

    • Updated CI workflow configuration and build processes.
    • Added configuration schemas for system adapters and runtime settings.
    • Enhanced repository structure and ignore patterns.
    • Established infrastructure and operational documentation standards.

- AppShell: remove lg:overflow-hidden on main in dashboard mode to prevent panel cutoff on large viewports (overflow-auto retained throughout)
- Sidebar: wrap AgentChatMirror in min-h-0 shrink container so tall chat panel no longer displaces nav items off-screen
- TopBar: fix stale data — was fetch-on-mount only; add 10 000 ms setInterval refresh for system snapshot, notifications, and proof bundle (non-critical display data)
- globals.css: no changes needed (font-size 13px and dashboard-grid overflow-hidden are intentional)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 8, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR establishes the Hermes3D OS baseline and foundation: it enforces new and expanded contracts/policies on UI, agent/operator, and user/physical safety, creates a comprehensive JSON Schema registry for all adapters and configs, documents fleet/printer/source state, introduces machine-verifiable proof artifacts, and builds a dense, indexed audit/merge/docs/handoff chain with rigorous CI/test enforcement.

Changes

OS Completion, Policy, Registry, Audit, and Test Foundation

Layer / File(s) Summary
Policy, Contracts, Roadmap, and Agent Safety
`00_overview/contract/`, `01_requirements/`, `03_implementation/ROADMAP.md`
Defines and extends the master policy and completion contract, forbidden fake state and operator/agent handling, enhanced agent/operator delegation, and printer fleet live/operator safety configuration and rules.
Adapter Registry Schemas & Validation Contracts
`03_implementation/adapter_registry/schemas/*.json`
Creates a deep, strict registry of JSON Schemas for all relevant adapter/config types: slicers, modelers, firmware, toolchains, gates, jobs/steps, printers, app/plugin/runtime/ports, proof/result artifacts and settings.
Printer Fleet Config, Source OS, .gitignore
`03_implementation/config/printers.toml`, `.gitignore`
Updates printer configs (S1/T1/V400) with official URLs, config topics, and safety policies. Expands .gitignore to include UI runtime artifacts and mark-exclude Source OS upstream folders.
Proof, Firmware, Fleet, Tab-Audit Machine Evidence
`03_implementation/proof/*.json`, `03_implementation/proof/ACTIVE_UI_NO_FAKE_SWEEP.md`
Adds and updates extensive machine-readable proof artifacts: tab-audit no-fake results, FLSUN fleet profile audit JSON, firmware verification runs, gen3d environment checks.
Documented Audit, Handoffs, Indices, Merge Safety, and Enhancement Records
`03_implementation/docs/**/*`
Includes exhaustive documentation: multi-agent handoff contracts, index and taxonomy, merge integrity, audit and queue docs, tab/feature mapping, physical IO and security audits, source/packages/app-index overviews, enhancement/handoff and completion mapping, diagrams, and queue/merge status.
CI Workflow, PR Live Test/No-Fake, .gitignore Expansion
`.github/workflows/ui-ci.yml`, `.gitignore`
CI: expands PR triggers, adds Python/NPM/playwright live-test steps, enforces proof/no-fake + Playwright run for GUI sign-off, and adds .gitignore rules for new runtime artifacts.

Sequence Diagram(s)

sequenceDiagram
  participant Policy
  participant AdapterSchemas
  participant CI
  participant Playwright
  Policy->>CI: Sets sign-off/no-fake gate rules
  Policy->>AdapterSchemas: Defines required schemas & contract structure
  AdapterSchemas->>CI: Validates configs on commit/PR
  CI->>Playwright: Runs e2e/no-fake proof tests
  Playwright-->>CI: Results required for merge
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • Ghenghis/Hermes3D#8: Edits MASTER_CONTRACT.md and directly relates to Wave B reviewer evaluations on the contract.
  • Ghenghis/Hermes3D#14: Both PRs modify .github/workflows/ui-ci.yml to change Playwright job triggers and setup.
  • Ghenghis/Hermes3D#13: Both PRs modify the CI UI workflow and Playwright invocation/targets.

Poem

A rabbit hops through contracts, so neat,
With schemas for every adapter it’ll meet.
Proofs align, audits parade,
Printers and agents in order arrayed.
CI declares, "All passes, all true!"
In Hermes3D fields, the reviews are new.
🐇✨

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude24/i10-perf-shell
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch claude24/i10-perf-shell

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request significantly expands the Hermes3D OS documentation and infrastructure, establishing strict 'Definition of Done' rules against data fabrication and defining the operational boundaries for Hermes Agents as user delegates. It introduces a comprehensive roadmap for tab completion, a suite of JSON schemas for adapter registries, and detailed audit reports for runtime truth and printer safety. Feedback identified a typo in the printer configuration, an inconsistent JSON schema draft version, and a hardcoded Windows path that limits portability.

moonraker_url = "http://flsun-t1-a.local"
api_key = ""
official_wiki_url = "https://wiki.flsun3d.com/en/FlsunT1"
official_config_topics = ["Network Connection Guidelines", "Orca import T1 configurationfile", "First Printing with Local Test Models"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Typo: 'configurationfile' should be 'configuration file'.

Suggested change
official_config_topics = ["Network Connection Guidelines", "Orca import T1 configurationfile", "First Printing with Local Test Models"]
official_config_topics = ["Network Connection Guidelines", "Orca import T1 configuration file", "First Printing with Local Test Models"]

@@ -0,0 +1,79 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Inconsistent JSON schema draft version. Please use https://json-schema.org/draft/2020-12/schema for consistency with other schemas in this directory.

Suggested change
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",

"string",
"null"
],
"default": "C:/Program Files/Bambu Studio/bambu-studio.exe",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Hardcoded Windows path detected. This reduces portability. Consider using an environment variable or a relative path.

Suggested change
"default": "C:/Program Files/Bambu Studio/bambu-studio.exe",
"default": "bambu-studio.exe",

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 16

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (32)
03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-wire-tasks/h3dos-wire-action-window-pin.md-11-11 (1)

11-11: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove machine-local absolute path from the handoff doc.

Line 11 embeds a local filesystem path (G:\...), which is environment-specific and unnecessary in repo docs. Prefer repo-relative path or omit it.

Suggested doc edit
-- **Path**: `G:\Github\h3dos-wire-action-window-pin`
+- **Path**: `apps/web/action-window.js` and `tests/e2e/wire-action-window-pin.spec.ts`
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-wire-tasks/h3dos-wire-action-window-pin.md`
at line 11, Remove the machine-local absolute path string
`G:\Github\h3dos-wire-action-window-pin` from the handoff doc and either replace
it with a repo-relative path (for example `./h3dos-wire-action-window-pin` or
`h3dos-wire-action-window-pin`) or omit the Path line entirely so the document
contains no environment-specific filesystem references.
03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/merge-prs/README.md-31-36 (1)

31-36: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language tag to the fenced code block.

The fence starting at Line 31 is missing a language identifier, which triggers markdownlint MD040.

Suggested fix
-```
+```text
 merge-pr23  branch=feat/gate-dep-fresh                      HEAD=b2a518b  status=clean  COMPLETE
 merge-pr24  branch=feat/gate-sbom                           HEAD=2455244  status=clean  COMPLETE
 merge-pr27  branch=feat/gate-mcp-scan-static                HEAD=398c9b9  status=clean  COMPLETE
 merge-pr33  branch=feat/mcp-supervisor-auto-reconnect       HEAD=1ff4e64  status=clean  COMPLETE
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/merge-prs/README.md
around lines 31 - 36, The fenced code block that lists merge-pr23/24/27/33 is
missing a language tag (triggering markdownlint MD040); update the
triple-backtick that begins the block (the fence containing the lines starting
with "merge-pr23") to include a language identifier such as text or console
(e.g., change totext) so the block is explicitly tagged while leaving
the block contents unchanged.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/core-repos/h3d-gui-wiring-codex.md-15-26 (1)</summary><blockquote>

`15-26`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Add a language tag to the fenced commit-log block.**

The fence starting at Line 15 has no language, which triggers markdownlint MD040.

 
<details>
<summary>Suggested edit</summary>

```diff
-```
+```text
 485155b 2026-05-07 feat(agents): add provider execution artifacts
 4f7d316 2026-05-07 feat(agents): add provider team assignment lane
 30b42c0 2026-05-07 feat(agents): add proof-gated git shipping lane
 128263b 2026-05-06 fix(agents): harden code operator lane
 dc2070d 2026-05-06 docs(handoff): add Claude final audit takeover contract
 c1a1064 2026-05-06 feat(agents): add MCP-locked code operator lane
 f58a65a 2026-05-06 fix(ui): clear post-merge npm audit vulnerabilities (`#82`)
 9bb39f3 2026-05-06 docs(handoff): final Codex takeover bundle — 9 audit/merge/lock files (`#81`)
 6c08cc2 2026-05-06 audit(nofake-ui): 0 violations — 33 buttons wired + 0 lane TS errors (`#79`)
 30661b9 2026-05-06 audit(docs): PR body completeness + ROADMAP truth + merge plan verification (`#78`)
 ```
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/core-repos/h3d-gui-wiring-codex.md
around lines 15 - 26, The fenced commit-log block (the triple-backtick block
containing the commit hashes like "485155b 2026-05-07 feat(agents): add provider
execution artifacts") is missing a language tag which triggers markdownlint
MD040; fix it by adding a language identifier such as text (e.g., change the
opening "" to "text") so the block is explicitly marked as plain text and
the linter will stop flagging MD040.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-wire-tasks/h3dos-wire-dashboard-events-tail.md-13-20 (1)</summary><blockquote>

`13-20`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Fix conflicting PR `#30` commit SHA references.**

Line 13 and Line 20 cite different SHAs for the same PR `#30` commit (`d9e908d` vs `d9e98ed`). Please reconcile to one canonical value so the handoff remains auditable.

 
<details>
<summary>Suggested edit</summary>

```diff
-**OPEN / IN-DEVELOP** — PR `#30` commit `d9e98ed` is on `origin/develop`; not on `origin/main`.
+**OPEN / IN-DEVELOP** — PR `#30` commit `d9e908d` is on `origin/develop`; not on `origin/main`.
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-wire-tasks/h3dos-wire-dashboard-events-tail.md`
around lines 13 - 20, The document references two different SHAs for PR `#30`
(d9e908d and d9e98ed); verify the correct commit SHA for PR `#30` in the git
history and update both occurrences so they match the canonical SHA for that PR;
ensure surrounding references to related commits (3cf7a54 and 439699c) remain
unchanged and that the commit SHA is consistent across the paragraph describing
the status.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/worktree-collections/_codex_worktrees.md-8-8 (1)</summary><blockquote>

`8-8`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Detached-HEAD totals are inconsistent.**

Line 8 says 7 detached worktrees, while the legend at Line 67 says 6 (and the inventory appears to support 6). Please align the count.




Also applies to: 67-67

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/worktree-collections/_codex_worktrees.md`
at line 8, The "Note: 7 worktrees are at detached HEAD (no symbolic branch
ref)." sentence is inconsistent with the legend count "6" and the inventory;
reconcile by recounting detached worktrees and update the string "Note: 7
worktrees are at detached HEAD (no symbolic branch ref)." or the legend entry so
both show the same number (likely changing 7 to 6), and ensure any other
occurrences of "Detached-HEAD" totals in this document (e.g., the legend line)
are updated to match the corrected total.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/hermesproof/hermesproof-trigger-sandbox.md-12-12 (1)</summary><blockquote>

`12-12`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Resolve gate-run count mismatch in this doc.**

Line 12 says “three gate runs,” but Line 30 and Line 87 both say 6 captured gate runs. Please normalize these counts to one source of truth.




Also applies to: 30-30, 87-87

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/hermesproof/hermesproof-trigger-sandbox.md`
at line 12, The document currently has conflicting counts: the phrase "three
gate runs" and two occurrences of "6 captured gate runs"; pick the correct
canonical count (either 3 or 6) and make them consistent by updating every
occurrence of the strings "three gate runs" and "6 captured gate runs" to the
chosen value (also update any number words like "three" -> "six" or vice versa)
including the summary sentence referencing the gate-run count and the later
lines that say "6 captured gate runs" so the whole doc uses a single
source-of-truth count for gate runs.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/adapter_registry/schemas/runtime_ports.schema.json-14-14 (1)</summary><blockquote>

`14-14`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Consider raising the minimum port to 1024 to avoid privileged port range.**

All port properties currently allow `minimum: 1`, which includes the privileged/well-known port range (1-1023). Binding to ports below 1024 typically requires elevated privileges and may conflict with system services. While your defaults are safely in the unprivileged range, the schema permits configuration values that would cause runtime permission errors.




<details>
<summary>🔒 Proposed fix to restrict to unprivileged ports</summary>

```diff
     "api": {
       "type": "integer",
-      "minimum": 1,
+      "minimum": 1024,
       "maximum": 65535,
       "default": 7862
     },
     "web": {
       "type": "integer",
-      "minimum": 1,
+      "minimum": 1024,
       "maximum": 65535,
       "default": 5173
     },
     "camera_proxy": {
       "type": "integer",
-      "minimum": 1,
+      "minimum": 1024,
       "maximum": 65535,
       "default": 8080
     },
     "telemetry": {
       "type": "integer",
-      "minimum": 1,
+      "minimum": 1024,
       "maximum": 65535,
       "default": 9090
     },
     "model_llm": {
       "type": "integer",
-      "minimum": 1,
+      "minimum": 1024,
       "maximum": 65535,
       "default": 11434
     }
```
</details>



Also applies to: 20-20, 26-26, 32-32, 38-38

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@03_implementation/adapter_registry/schemas/runtime_ports.schema.json` at line
14, The schema allows ports with "minimum": 1 which permits privileged ports;
update each port property in runtime_ports.schema.json that currently sets
"minimum": 1 to "minimum": 1024 so only unprivileged ports are allowed (repeat
for all occurrences flagged in the review), keeping existing "maximum" and other
constraints unchanged and ensuring any example/default values still fall within
the new range; locate these by searching for the "minimum": 1 entries associated
with port-related property names in the schema and change their value to 1024.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-codex-tasks/h3dos-codex-prusaslicer.md-40-40 (1)</summary><blockquote>

`40-40`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Keep installer method naming consistent across text and SVG.**

Line 40 references `_install_binary_download`, but Line 66 shows `_install_binary`.


<details>
<summary>Suggested doc fix</summary>

```diff
-  <text class="small" x="170" y="154">_install_binary</text>
+  <text class="small" x="170" y="154">_install_binary_download</text>
```
</details>


Also applies to: 66-66

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-codex-tasks/h3dos-codex-prusaslicer.md`
at line 40, The verifier name is inconsistent: the doc references
`_install_binary_download` in one place but `_install_binary` elsewhere; pick
the correct installer function name used in code (e.g., the actual function
defined in `apps/api/hermes3d_api/source_install.py`) and update all occurrences
in the markdown and any embedded SVGs to match that exact symbol
(`_install_binary_download` or `_install_binary`), ensuring header/labels and
the Verifier table entry use the same identifier and spelling.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/02_EXCLUSIONS.md-5-5 (1)</summary><blockquote>

`5-5`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Use canonical `GitHub` casing in the path text.**

Lines 5, 53, and 67 use `G:\Github\`; use `G:\GitHub\` for consistent platform naming in docs.


<details>
<summary>Suggested doc fix</summary>

```diff
-This document lists every folder under `G:\Github\` that fell within the date filter (2026-04-27 → 2026-05-07) but was **excluded** from the Hermes3D OS folder index, and the reason for each exclusion.
+This document lists every folder under `G:\GitHub\` that fell within the date filter (2026-04-27 → 2026-05-07) but was **excluded** from the Hermes3D OS folder index, and the reason for each exclusion.
...
-The following folders exist in `G:\Github\` but were modified **before 2026-04-27** and are not included in this index regardless of relevance:
+The following folders exist in `G:\GitHub\` but were modified **before 2026-04-27** and are not included in this index regardless of relevance:
...
-- `Hermes3D-OS/_claude_worktrees/` — visible only as a child of `Hermes3D-OS`. The `_claude_worktrees/` at the *top level* of `G:\Github\` is the canonical multi-worktree umbrella covered by `worktree-collections/_claude_worktrees.md`.
+- `Hermes3D-OS/_claude_worktrees/` — visible only as a child of `Hermes3D-OS`. The `_claude_worktrees/` at the *top level* of `G:\GitHub\` is the canonical multi-worktree umbrella covered by `worktree-collections/_claude_worktrees.md`.
```
</details>


Also applies to: 53-53, 67-67

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/02_EXCLUSIONS.md`
at line 5, Replace every occurrence of the path string "G:\Github\" in
02_EXCLUSIONS.md with the canonical casing "G:\GitHub\" (the instances to update
are the literal text "G:\Github\" found in the document, e.g., the
header/introduction and the two other occurrences noted); ensure the replacement
preserves surrounding backticks and formatting so the text becomes `G:\GitHub\`
everywhere for consistent platform naming.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/INTEGRATION_REPORT_2026-05-06.md-141-145 (1)</summary><blockquote>

`141-145`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Specify a language for the fenced block to satisfy MD040.**

Add a fence language (e.g., `text`) on Line 141.


<details>
<summary>Suggested markdown fix</summary>

```diff
-```
+```text
 Batch 1 (parallel): `#53`, `#54`, `#55`, `#56`, `#57`, `#58`, `#59`, `#60`, `#61`, `#62`, `#63`, `#65`, `#67`, `#68`, `#70`
 Batch 2 (sequential): `#66` → `#69`  (resolve app.py union)
 Batch 3 (sequential): `#64` → `#71`  (resolve adapters.ts / adapters.live.ts union)
 ```
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @03_implementation/docs/handoffs/INTEGRATION_REPORT_2026-05-06.md around
lines 141 - 145, The fenced code block that starts with "Batch 1 (parallel):
#53, #54, ..." is missing a language hint and triggers MD040; update the opening
fence () to include a language token such as text (e.g., change to
text) so the block reads text and leave the rest unchanged, ensuring the
three-line fenced block containing "Batch 1 (parallel): ...", "Batch 2
(sequential): ...", and "Batch 3 (sequential): ..." is annotated.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-codex-tasks/h3dos-codex-prusaslicer.md-37-46 (1)</summary><blockquote>

`37-46`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Add blank lines around the `Key files` table to satisfy markdownlint.**

This section currently triggers MD058.


<details>
<summary>Suggested markdown fix</summary>

```diff
 ## Key files
+
 | Role | Path |
 |---|---|
 | Verifier | `apps/api/hermes3d_api/source_install.py::_install_binary_download` (line 467) |
 | Subprocess probe | `source_install.py` lines 304, 344 (binary smoke checks) |
 | Launcher | `apps/api/hermes3d_api/main.py` PrusaSlicer launch path (line 766+) |
 | Registry / schema | `apps/web/source_manifest.json` line 8, `source-lab/source_manifest.json` |
 | E2E test | `tests/e2e/app-prusaslicer.spec.ts` |
+
 ## Integration path diagram
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-codex-tasks/h3dos-codex-prusaslicer.md`
around lines 37 - 46, The markdown table under the header "## Key files"
violates MD058 because there are no blank lines surrounding it; edit the
h3dos-codex-prusaslicer.md content near the "## Key files" section and add a
blank line after the "## Key files" heading and another blank line after the
table block (the table rows referencing
Verifier::apps/api/hermes3d_api/source_install.py::_install_binary_download,
Subprocess probe::source_install.py, Launcher::apps/api/hermes3d_api/main.py,
Registry/schema::apps/web/source_manifest.json and E2E
test::tests/e2e/app-prusaslicer.spec.ts) so the table is separated by empty
lines from surrounding text.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/02_EXCLUSIONS.md-65-67 (1)</summary><blockquote>

`65-67`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Fix the stated folder count in this section.**

Line 65 says “Two folders” but only one folder is listed (Line 67). Update the count or add the missing second entry.


<details>
<summary>Suggested doc fix</summary>

```diff
-Two folders dated within the window contain Hermes3D content but are entirely covered by other categories' deeper inspection:
+One folder dated within the window contains Hermes3D content but is entirely covered by another category's deeper inspection:
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/02_EXCLUSIONS.md`
around lines 65 - 67, The heading text says "Two folders" but the list contains
only one entry (`Hermes3D-OS/_claude_worktrees/`), so either change the count to
"One folder" or add the missing second folder entry; locate the section that
contains the phrase "Two folders" and update it to "One folder" if there's no
second item, or add the second folder (ensuring it matches the same coverage
criteria as `Hermes3D-OS/_claude_worktrees/` and/or references
`worktree-collections/_claude_worktrees.md`) so the count and list are
consistent.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-codex-tasks/h3dos-codex-octoprint.md-40-48 (1)</summary><blockquote>

`40-48`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Add a blank line before the `Key files` table.**

Line 41 starts the table immediately after the heading; markdownlint MD058 expects a surrounding blank line.

 

<details>
<summary>Proposed fix</summary>

```diff
 ## Key files
+
 | Role | Path |
 |---|---|
 | Verifier / install dispatcher | `apps/api/hermes3d_api/source_install.py` (`_install_pip`, line 326) |
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-codex-tasks/h3dos-codex-octoprint.md`
around lines 40 - 48, Add a blank line between the "Key files" heading and the
table in h3dos-codex-octoprint.md so the table is separated from the heading
(fixes markdownlint MD058); edit the `## Key files` section in the file and
insert one empty line before the table that begins with "| Role | Path |".
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-codex-tasks/h3dos-codex-blender-cli.md-36-44 (1)</summary><blockquote>

`36-44`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Insert a blank line before the `Key files` table.**

Line 37 begins the table directly under the heading; this violates MD058.

 

<details>
<summary>Proposed fix</summary>

```diff
 ## Key files
+
 | Role | Path |
 |---|---|
 | Verifier | `apps/api/hermes3d_api/source_install.py::_install_clone` (line 367) |
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-codex-tasks/h3dos-codex-blender-cli.md`
around lines 36 - 44, Add a single blank line between the "## Key files" heading
and the following table to satisfy MD058; edit the markdown block under the "##
Key files" heading so the table (the pipe-delimited rows listing Verifier, Smoke
probe, Registry / schema, etc.) is separated by one empty line from the heading.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/claude-e2e-intelligence-2026-05-08/05_TAB_BY_TAB_ACTIVE_UI_NO_FAKE_AUDIT.md-21-21 (1)</summary><blockquote>

`21-21`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Escape/remove the pipe inside the Plugins routes cell to keep table columns intact.**

Line 21 uses `config|logs` in a table cell, which creates an extra column in markdown parsing.

 

<details>
<summary>Proposed fix</summary>

```diff
-| Plugins | `src/tabs/Plugins.tsx` | `adapters.getPlugins()`, `activatePlugin()`, `getModuleUpdateReadiness()`, `getModuleRuntimeSetupQueue()`, `planModuleRuntimeSetupQueue()`, `fetch(/api/plugins/{id}/config|logs)`, `emitProofEvent("plugins.plugin.state.changed")` | Left panel (plugin list) + right panel (config/logs/details), resizable divider | Part of Primary TABS, visible in Simple, same update-readiness status | NEEDED — plugin activate/state-change wiring complete; update-readiness summary live; transcript/proof review UI next; setup queue status visible but plan execution remains proof-gated | PARTIAL |
+| Plugins | `src/tabs/Plugins.tsx` | `adapters.getPlugins()`, `activatePlugin()`, `getModuleUpdateReadiness()`, `getModuleRuntimeSetupQueue()`, `planModuleRuntimeSetupQueue()`, `fetch(/api/plugins/{id}/config)`, `fetch(/api/plugins/{id}/logs)`, `emitProofEvent("plugins.plugin.state.changed")` | Left panel (plugin list) + right panel (config/logs/details), resizable divider | Part of Primary TABS, visible in Simple, same update-readiness status | NEEDED — plugin activate/state-change wiring complete; update-readiness summary live; transcript/proof review UI next; setup queue status visible but plan execution remains proof-gated | PARTIAL |
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/claude-e2e-intelligence-2026-05-08/05_TAB_BY_TAB_ACTIVE_UI_NO_FAKE_AUDIT.md`
at line 21, The table cell containing `fetch(/api/plugins/{id}/config|logs)`
breaks Markdown columns due to the pipe; update the Plugins routes cell by
escaping the pipe (replace `|` with `\|`), or list the endpoints separately
(e.g., `fetch(/api/plugins/{id}/config)` and `fetch(/api/plugins/{id}/logs)`
separated by a comma) so the table columns remain intact — edit the cell text
containing fetch(/api/plugins/{id}/config|logs) in the Plugins row.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/security/MCP_BOUNDARY_NOTES.md-31-37 (1)</summary><blockquote>

`31-37`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Escape pipe characters in the table cell to prevent broken Markdown rendering.**

The `fail_threshold='high'|'medium'|'low'` cell introduces extra columns in Markdown tables. Escape pipes (or use HTML entities) inside the cell.

 

<details>
<summary>Suggested patch</summary>

```diff
-| Injection scanner fail-closed | `InjectionScanner(fail_threshold='high'|'medium'|'low')` | `ScanResult.fail_closed=True` when severity >= threshold |
+| Injection scanner fail-closed | `InjectionScanner(fail_threshold='high'\|'medium'\|'low')` | `ScanResult.fail_closed=True` when severity >= threshold |
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@03_implementation/docs/security/MCP_BOUNDARY_NOTES.md` around lines 31 - 37,
The Markdown table row containing
InjectionScanner(fail_threshold='high'|'medium'|'low') is breaking the table
because the pipe characters inside that cell are parsed as column separators;
update the table to escape those pipes (e.g., replace '|' with '\|' or HTML
entity '&#124;') inside the fail_threshold cell so the entire cell remains a
single column, and verify other cells such as module_runtime._redact_text and
local_state.assert_build_plate_clear are unchanged and render correctly.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/claude-e2e-intelligence-2026-05-08/01_GITHUB_FOLDER_ECOSYSTEM_AUDIT.md-169-171 (1)</summary><blockquote>

`169-171`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Fix the upstream-remediation command to match the stated deleted remote branch.**

Given the document says the upstream ref is deleted, `git branch -u origin/chore/exclude-apps-folder` is not a valid remediation unless the remote ref is recreated first.

 

<details>
<summary>Suggested correction</summary>

```diff
-`git branch -u origin/chore/exclude-apps-folder` or delete dangling branch.
+`git branch --unset-upstream` (or delete/recreate the branch with a valid remote tracking ref).
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/claude-e2e-intelligence-2026-05-08/01_GITHUB_FOLDER_ECOSYSTEM_AUDIT.md`
around lines 169 - 171, The remediation command currently sets the Hermes3D
branch upstream to origin/chore/exclude-apps-folder which no longer exists;
update the instruction to match the deleted remote by either instructing to
unset the upstream for the Hermes3D branch (remove its upstream tracking) or to
delete the local Hermes3D branch entirely, or alternatively note that the
upstream command is valid only if the remote branch
origin/chore/exclude-apps-folder is recreated first.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/audit/SECURITY_MCP_2026-05-06.md-19-22 (1)</summary><blockquote>

`19-22`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Add language identifiers to fenced code blocks (MD040).**

The fences near Line 19 and Line 107 are missing language tags, which triggers markdownlint.

 
<details>
<summary>Proposed fix</summary>

```diff
-```
+```text
 Voice.tsx:328  "Catalog rows come from Azure Speech through the Python backend. The frontend never receives the Speech key."
 Voice.tsx:370  "<div>Set `AZURE_SPEECH_KEY` and `AZURE_SPEECH_REGION` in `G:\\private\\.env` to load the live Azure catalog.</div>"
 ```

-```
+```gitignore
 .env
 .env.local
 .env.*.local
 ```
```
</details>


Also applies to: 107-113

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @03_implementation/docs/handoffs/audit/SECURITY_MCP_2026-05-06.md around
lines 19 - 22, The markdown code fences shown (e.g., the blocks containing
"Voice.tsx:328 'Catalog rows come from Azure Speech...'" and "Voice.tsx:370
'

Set AZURE_SPEECH_KEY...'>" and the block around lines 107-113) are
missing language identifiers; update those fences to include appropriate
languages (for example use ```text for the inline Voice.tsx snippets and

each opening triple-backtick is followed by the language token and the closing
fence remains ``` to match.
03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-codex-tasks/h3dos-codex-triposr.md-39-42 (1)

39-42: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add blank line before the table to satisfy markdownlint MD058.

Line 40 starts the table immediately after the heading; add a separating blank line.

Proposed fix
 ## Key files
+
 | Role | Path |
 |---|---|
 | Verifier | `apps/api/hermes3d_api/source_install.py::_install_clone_full_venv` (line 413) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-codex-tasks/h3dos-codex-triposr.md`
around lines 39 - 42, Add a blank line between the "## Key files" heading and
the table so the table is not directly adjacent to the heading (this satisfies
markdownlint MD058); edit the markdown in h3dos-codex-triposr.md and insert an
empty line immediately before the table that references
`apps/api/hermes3d_api/source_install.py::_install_clone_full_venv` to separate
the heading from the table.
03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/core-repos/Hermes3D.md-15-20 (1)

15-20: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Specify a language for the fenced block.

Line 15 uses an unlabeled fenced code block, triggering markdownlint MD040.

Suggested patch
-```
+```text
 6020de8 2026-05-03 chore: fully exclude apps/ from git (vendored installs, local-only)
 5b11f6c 2026-05-03 docs(adr): ADR-014 — audit of blender-mcp-native (verdict: REJECT)
 c3e68d1 2026-05-03 docs(handoff): overnight Codex queue — 1 master + 6 task briefs + roadmap
 b767100 2026-05-03 feat(backup): local-only secrets backup — Syncthing + Restic-B2 scripts
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/core-repos/Hermes3D.md
around lines 15 - 20, The fenced code block listing commit lines in Hermes3D.md
is unlabeled and triggers markdownlint MD040; update the opening fence from to include a language label (e.g.,text) so the block becomes a labeled
fenced code block, ensuring the closing fence remains ``` and the block content
is unchanged.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/claude-e2e-intelligence-2026-05-08/03_HERMES_AGENT_RUNTIME_GAP_MAP.md-15-20 (1)</summary><blockquote>

`15-20`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Add a language identifier to the fenced block.**

Line 15 opens a fenced code block without a language, which will keep markdownlint warning MD040 active.

 
<details>
<summary>Suggested patch</summary>

```diff
-```
+```text
 6020de8 2026-05-03 chore: fully exclude apps/ from git (vendored installs, local-only)
 5b11f6c 2026-05-03 docs(adr): ADR-014 — audit of blender-mcp-native (verdict: REJECT)
 c3e68d1 2026-05-03 docs(handoff): overnight Codex queue — 1 master + 6 task briefs + roadmap
 b767100 2026-05-03 feat(backup): local-only secrets backup — Syncthing + Restic-B2 scripts
 ```
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@03_implementation/docs/handoffs/claude-e2e-intelligence-2026-05-08/03_HERMES_AGENT_RUNTIME_GAP_MAP.md
around lines 15 - 20, Add a language identifier to the fenced code block that
contains the commit list (starts with "6020de8 2026-05-03 chore: fully exclude
apps/...") to silence markdownlint MD040; replace the opening with a labeled fence such astext (or ```diff) so the block is explicitly typed while
leaving the contents unchanged.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/audit/MERGE_INTEGRITY_2026-05-06.md-44-48 (1)</summary><blockquote>

`44-48`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Add language tag to fenced block**

The code fence at Line 44 has no language identifier (MD040).




<details>
<summary>Suggested fix</summary>

```diff
-```
+```text
 modules, jobs, approvals, artifacts, plugins, voice, learning, roadmap, design,
 generation, printers, settings, system, ports, autopilot, code_operator, events,
 agents, agent_updates, desktop_compat, desktop_updates, autonomous, notifications, observe
 ```
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @03_implementation/docs/handoffs/audit/MERGE_INTEGRITY_2026-05-06.md around
lines 44 - 48, The fenced code block in MERGE_INTEGRITY_2026-05-06.md (the list
starting with "modules, jobs, approvals...") is missing a language tag; update
that fence to include a language identifier (e.g., add text) so the block becomes text ... ``` to satisfy MD040 and ensure proper linting/rendering.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/claude-e2e-intelligence-2026-05-08/09_CODEX_NEXT_50_TASKS.md-67-67 (1)</summary><blockquote>

`67-67`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Fix circular prerequisite text in Task 11**

Line 67 references `11's plan` within Task 11 itself, creating a circular prerequisite in the table.




<details>
<summary>Suggested fix</summary>

```diff
-| 11 | P0 | **Gpu-worker-gap**: Microsoft TRELLIS.2 + Tencent Hunyuan3D 2.1 + TripoSR dependency/model-cache verifiers (read-only python import + cache path stat, no GPU job launch) | `verifiers/gpu_dependency.py` (new), 3 verify routes, ROADMAP entry | tasks 8 + 11's plan | 3 verifiers report ready/blocked w/ model path proof | med | yes after Tier 1 |
+| 11 | P0 | **Gpu-worker-gap**: Microsoft TRELLIS.2 + Tencent Hunyuan3D 2.1 + TripoSR dependency/model-cache verifiers (read-only python import + cache path stat, no GPU job launch) | `verifiers/gpu_dependency.py` (new), 3 verify routes, ROADMAP entry | task 8 | 3 verifiers report ready/blocked w/ model path proof | med | yes after Tier 1 |
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/claude-e2e-intelligence-2026-05-08/09_CODEX_NEXT_50_TASKS.md`
at line 67, The table row for Task 11 ("Gpu-worker-gap") contains a circular
prerequisite text "11's plan"; remove that self-reference and replace it with a
non-circular reference that points to the actual prerequisite plan (for example
"see Task 8's plan" or "see Task 8 plan"), updating the cell that currently
reads "tasks 8 + 11's plan" so it no longer references Task 11 itself; ensure
the entry for Gpu-worker-gap / `verifiers/gpu_dependency.py` mentions the
correct dependent task(s) instead of "11's plan".
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/audit/RUNTIME_TRUTH_2026-05-06.md-109-109 (1)</summary><blockquote>

`109-109`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Remove trailing spaces inside inline code spans**

Line 109 includes code spans with trailing spaces (MD038): `` `G28 ` `` and `` `M104 ` ``.




<details>
<summary>Suggested fix</summary>

```diff
-Live integration tests use `@pytest.mark.parametrize` from actual proof file — only runs if the executable is confirmed installed and `Path(exe_path).is_file()` is True. G-code safety guard checks that probe output does not contain G-code markers (`;LAYER:`, `G28 `, `M104 `).
+Live integration tests use `@pytest.mark.parametrize` from actual proof file — only runs if the executable is confirmed installed and `Path(exe_path).is_file()` is True. G-code safety guard checks that probe output does not contain G-code markers (`;LAYER:`, `G28`, `M104`).
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@03_implementation/docs/handoffs/audit/RUNTIME_TRUTH_2026-05-06.md` at line
109, Remove the trailing spaces inside the inline code spans in the markdown
sentence that lists G-code safety markers: locate the backticked spans referring
to G28 and M104 and edit them to eliminate the trailing space characters so the
inline code tokens read without trailing whitespace (e.g., change the `G28 ` and
`M104 ` spans to versions without the trailing space).
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/adapter_registry/schemas/moonraker_api.schema.json-55-58 (1)</summary><blockquote>

`55-58`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Constrain `timeout_seconds` to positive values**

`timeout_seconds` has a max but no minimum, so zero/negative values currently pass validation.




<details>
<summary>Suggested fix</summary>

```diff
         "timeout_seconds": {
           "type": "number",
+          "minimum": 0.1,
           "default": 2.0,
           "maximum": 10.0,
           "description": "HTTP request timeout"
         }
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@03_implementation/adapter_registry/schemas/moonraker_api.schema.json` around
lines 55 - 58, The timeout_seconds property currently has a maximum but no lower
bound; update the schema for "timeout_seconds" (the property with "type":
"number", "default": 2.0, "maximum": 10.0) to require positive values by adding
an exclusiveMinimum: 0 (or set minimum: 0.0 with exclusiveMinimum if you prefer
clarity) so zero/negative values fail validation.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/core-repos/Hermes3D-OS.md-15-26 (1)</summary><blockquote>

`15-26`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Add a language identifier to the fenced code block**

The fence starting at Line 15 is missing a language, which triggers markdownlint MD040.




<details>
<summary>Suggested fix</summary>

```diff
-```
+```text
 e9c22e8 2026-05-04 Windsurf-4: Agents Dispatch, Learning Bookmark, Artifacts Download, Approvals Approve/Reject buttons (`#31`)
 ccfd189 2026-05-04 feat(wire/artifacts-row-click): artifact row → Action Window (`#44`)
 4871302 2026-05-04 feat(wire/action-window-history): back/fwd navigation in Action Window (`#34`)
 4515d6b 2026-05-04 wire(global-event-bus-logger): debug logger on actionwindow:render when ?debug=1 (`#46`)
 d0ee37d 2026-05-04 feat(ui): font scale popover + Codex handoff prompts (`#9`)
 9da8f72 2026-05-04 docs(handoffs): 4-agent split plan (Claude/Codex/Kilocode/Windsurf) (`#10`)
 6b2f5fe 2026-05-04 feat: add UI settings with persistence and E2E tests (Windsurf-1) (`#17`)
 e43917f 2026-05-04 wire(approvals-pending-actionwindow): approval row → Action Window (`#47`)
 0938671 2026-05-04 wire(observe-camera-tile-click): camera tile → Action Window (`#41`)
 7985de0 2026-05-04 wire(learning-topics-actionwindow): learning topic -> Action Window (`#39`)
 ```
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/core-repos/Hermes3D-OS.md
around lines 15 - 26, The fenced code block that begins with the line "e9c22e8
2026-05-04 Windsurf-4: Agents Dispatch, Learning Bookmark, Artifacts Download,
Approvals Approve/Reject buttons (#31)" is missing a language tag and triggers
markdownlint MD040; update its opening fence from totext (or another
appropriate language like bash/diff/text) so the block reads text, leaving the block contents unchanged and keeping the closing as-is.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/source-os-60-apps/README.md-59-61 (1)</summary><blockquote>

`59-61`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Use a single canonical category key for 3D generation.**

The doc uses `three_d_generation` in the section list but `3d_generation` in the chart label. Keeping one canonical key avoids confusion when matching registry/category names.


<details>
<summary>🛠️ Suggested fix</summary>

```diff
-  <text x="14" y="180" class="l">3d_generation</text>
+  <text x="14" y="180" class="l">three_d_generation</text>
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/source-os-60-apps/README.md`
around lines 59 - 61, The README uses two inconsistent category keys:
"three_d_generation" in the section list and "3d_generation" in the SVG/chart
label; pick one canonical key (preferably "three_d_generation" for readability)
and replace the other to make them identical across the document, updating the
section list entry and the SVG <text> content (the label currently showing
3d_generation) so both use the same key; ensure any references in the file to
registry or category names (e.g., the section list and the chart label text
elements) are updated consistently.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/hermesproof/README.md-7-9 (1)</summary><blockquote>

`7-9`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Specify a language for the pipeline fence block.**

This fence has no language and will trip markdownlint MD040.


<details>
<summary>🛠️ Suggested fix</summary>

```diff
-```
+```text
 TRIGGER  →  WIZARD-GATES  →  QUEUE  →  NEXT-TASK (consumer)
 ```
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/hermesproof/README.md
around lines 7 - 9, The fenced code block showing the pipeline ("TRIGGER →
WIZARD-GATES → QUEUE → NEXT-TASK (consumer)") lacks a language tag and
triggers markdownlint MD040; edit the README.md fenced block around that
pipeline and add a language identifier (e.g., use "text") after the opening
backticks so the fence becomes ```text and the content remains unchanged,
ensuring the linter no longer flags MD040.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/core-repos/Hermes3D-handoffs.md-15-26 (1)</summary><blockquote>

`15-26`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Add a language identifier to the fenced commit-log block.**

This block is missing a fence language and will trigger MD040 in markdownlint.


<details>
<summary>🛠️ Suggested fix</summary>

```diff
-```
+```text
 d7336a5 2026-05-02 docs(handoff): HANDOFF_TO_CODEX_CP5.1-C.md (architect brief)
 e25fe7e 2026-05-02 Merge pull request `#17` from Ghenghis/feat/phase-3-4-real-provider-probes
 feb9f4f 2026-05-02 fix(phase3.4): expand proof to all six scenarios + tighten verifier (CP3.4-E1)
 a10d7b7 2026-05-02 chore(phase3.4): proof bundle + completion report + PR body (CP3.4-E)
 79aadaf 2026-05-02 feat(phase3.4): add providers/health bridge route + ui dot + playwright (CP3.4-D)
 1f16a73 2026-05-02 feat(phase3.4): wire R9/R10 + provider.probe capability + cli + integration (CP3.4-C)
 5023e70 2026-05-02 feat(phase3.4): add probe gateway + minimax/deepseek adapter substrate (CP3.4-B)
 2fe40b5 2026-05-02 feat(phase3.4): add Phase 3.4 plan + ADR-012 + extended policy schema (CP3.4-A)
 6231d33 2026-05-02 Merge pull request `#16` from Ghenghis/feat/phase-3-3-llm-planner-gateway
 e1df84d 2026-05-02 chore: remove accidental file from PR
 ```
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/core-repos/Hermes3D-handoffs.md
around lines 15 - 26, The fenced commit-log block in Hermes3D-handoffs.md lacks
a language identifier causing markdownlint MD040; update the opening fence for
the commit block (the triple-backtick before the commit lines) to include a
language token (e.g., ```text) so the block becomes a properly labeled fenced
code block and re-run linting to confirm MD040 is resolved.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/claude-e2e-intelligence-2026-05-08/08_PR_AND_MERGE_QUEUE.md-42-97 (1)</summary><blockquote>

`42-97`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Add language specifier to fenced code block.**

The ASCII-art PR chain visualization uses a fenced code block without a language identifier. While markdown parsers will still render it, adding an explicit language identifier improves compatibility and satisfies linting tools.




<details>
<summary>📝 Proposed fix</summary>

```diff
-```
+```text
                                          develop
                                             ▲
```

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@03_implementation/docs/handoffs/claude-e2e-intelligence-2026-05-08/08_PR_AND_MERGE_QUEUE.md
around lines 42 - 97, The fenced code block containing the ASCII-art PR chain
visualization in 08_PR_AND_MERGE_QUEUE.md is missing a language specifier;
update the opening fence for that block (the triple backticks before the ASCII
art) to include a language identifier such as text (e.g., change totext)
so markdown linters and parsers treat it as plain text and the lint warning is
resolved.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-codex-tasks/h3dos-codex-fluidd.md-36-43 (1)</summary><blockquote>

`36-43`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Add blank line before table.**

Markdown tables should be surrounded by blank lines for proper rendering and linting compliance.




<details>
<summary>📝 Proposed fix</summary>

```diff
 ## Key files
+
 | Role | Path |
 |---|---|
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-codex-tasks/h3dos-codex-fluidd.md`
around lines 36 - 43, The Markdown table under the "Key files" section lacks a
blank line above it; edit the document containing the "Key files" header and
insert a single blank line immediately before the table so the table is
separated from the preceding paragraph, ensuring proper rendering and linting
(locate the block that lists entries like
apps/api/hermes3d_api/source_install.py::_install_npm_build and
source_install.py and add the blank line right before the '| Role | Path |'
row).
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/core-repos/Hermes3D-worktrees.md-17-25 (1)</summary><blockquote>

`17-25`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Add language specifier to fenced code block.**

The commit history code block should specify `text` or `bash` as the language for proper syntax highlighting and markdown compliance.




<details>
<summary>📝 Proposed fix</summary>

```diff
-```
+```text
 1c6eeab test(bridge): relax provider-health assertion for ADR-015 chain
 0be0b9f feat: LM Studio default + Ollama fallback + Hipfire optional (ADR-015)
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/core-repos/Hermes3D-worktrees.md
around lines 17 - 25, The fenced code block showing the commit history (the
block that begins with lines like "1c6eeab test(bridge): relax provider-health
assertion for ADR-015 chain") needs a language specifier for proper Markdown
highlighting; update the opening fence from to a language-tagged fence such astext (or bash) so the block becomes text and leave the commit lines
unchanged.


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (9)</summary><blockquote>

<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/merge-prs/merge-pr23.md (1)</summary><blockquote>

`10-10`: _💤 Low value_

**Optional: Standardize GitHub capitalization.**

The platform name should be capitalized as "GitHub" rather than "Github" for consistency with the official branding.



<details>
<summary>📝 Proposed fix</summary>

```diff
-- **Worktree path**: G:\Github\merge-pr23
+- **Worktree path**: G:\GitHub\merge-pr23
```

Note: This assumes the actual directory can be renamed. If the path is a historical fact that cannot be changed, the documentation should remain as-is.
</details>


Also applies to: 32-32

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/merge-prs/merge-pr23.md`
at line 10, Update the platform name capitalization in the documented worktree
path: change the string "G:\Github\merge-pr23" to "G:\GitHub\merge-pr23" (edit
the value following the "Worktree path" label) and make the same capitalization
fix for the other occurrence referenced (the entry at the other "G:\Github..."
occurrence). Ensure both textual occurrences use the official "GitHub" casing.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/apps-vendored/OrcaSlicer-main.md (1)</summary><blockquote>

`12-12`: _💤 Low value_

**Optional: Standardize macOS capitalization.**

The operating system name should be capitalized as "macOS" rather than "macos" for consistency with Apple's official branding.



<details>
<summary>📝 Proposed fix</summary>

```diff
-- Build system: CMake (`CMakeLists.txt`, `build_release_vs2022.bat`, `build_linux.sh`, `build_release_macos.sh`, `build_flatpak.sh`)
+- Build system: CMake (`CMakeLists.txt`, `build_release_vs2022.bat`, `build_linux.sh`, `build_release_macOS.sh`, `build_flatpak.sh`)
```

```diff
-- `build_release_vs2022.bat`, `build_release_vs.bat`, `build_release.bat`, `build_linux.sh`, `build_release_macos.sh`, `build_flatpak.sh`
+- `build_release_vs2022.bat`, `build_release_vs.bat`, `build_release.bat`, `build_linux.sh`, `build_release_macOS.sh`, `build_flatpak.sh`
```
</details>


Also applies to: 33-33

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/apps-vendored/OrcaSlicer-main.md`
at line 12, Update occurrences of the lowercase OS name to Apple’s official
"macOS" in the documentation and any related references: change the prose in the
"Build system: CMake" line and anywhere the substring "macos" appears to "macOS"
(including visible filenames like build_release_macos.sh if you intend to rename
files; if you rename a file, also update all references to that filename such as
in CI, docs, or scripts), and ensure the same fix is applied to the other
reported occurrence mentioned in the comment.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/audit/PRINTER_SAFETY_2026-05-06.md (1)</summary><blockquote>

`15-23`: _⚡ Quick win_

**Prefer symbol/commit-permalink references over raw line numbers in audit claims.**

These checks are solid, but hard-coding many “line N” assertions will drift fast as code moves. Consider linking to commit permalinks and function/route names instead so this handoff stays verifiable longer.




Also applies to: 36-40, 53-60, 71-77, 157-167

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@03_implementation/docs/handoffs/audit/PRINTER_SAFETY_2026-05-06.md` around
lines 15 - 23, Replace brittle "line N" assertions in the audit with durable
references: cite the route/function names (e.g., probe_printer_by_ip,
test_printer, move_printer, upload_to_printer, upload_gcode_to_printer,
_validate_onboard_moonraker_url, _validated_onboard_printer_id,
_validated_onboard_model) and include a commit permalink (SHA/URL) for the exact
version verified instead of raw line numbers; update all similar occurrences
(including the ranges noted: 36-40, 53-60, 71-77, 157-167) so each PASS/FAIL
claim references the symbol and the commit permalink that was inspected.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-wire-tasks/h3dos-wire-artifacts-row-click.md (1)</summary><blockquote>

`15-43`: _💤 Low value_

**Consider using standard code fence for SVG.**

The code fence identifier `svg` is non-standard. For better compatibility and syntax highlighting, consider using `xml` instead:

```diff
-```svg
+```xml
 <svg xmlns="http://www.w3.org/2000/svg" width="400" height="250" viewBox="0 0 400 250">
```

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-wire-tasks/h3dos-wire-artifacts-row-click.md
around lines 15 - 43, The fenced block uses a non-standard svg code fence; change it to a standard xml fence so editors and highlighters recognize the
SVG markup—replace the opening svg with xml and keep the existing <svg
...> content unchanged (refer to the fenced block starting with the ```svg
marker and the element).


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-wire-tasks/h3dos-wire-jobs-search-filter.md (1)</summary><blockquote>

`29-51`: _💤 Low value_

**Consider using standard code fence for SVG.**

As with the artifact-row-click documentation, the `svg` fence identifier is non-standard. Use `xml` for better compatibility:

```diff
-```svg
+```xml
 <svg xmlns="http://www.w3.org/2000/svg" width="400" height="250" viewBox="0 0 400 250">
```

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/h3dos-wire-tasks/h3dos-wire-jobs-search-filter.md
around lines 29 - 51, The fenced SVG block uses a non-standard fence identifier
(svg) which can cause compatibility issues; change the opening and closing fenced code blocks from svg to ```xml so the block that begins with the "" line and its matching closing fence are updated to use xml instead of
svg.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/merge-prs/merge-pr33.md (1)</summary><blockquote>

`46-48`: _💤 Low value_

**Remove empty mermaid block.**

The empty mermaid code fence serves no purpose. Since the SVG diagram is already provided, this can be removed entirely.




<details>
<summary>🧹 Proposed cleanup</summary>

```diff
-## Diagram
-
-```mermaid
-%% (Mermaid optional — primary is the SVG below)
-```
-
 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 300" width="500" height="300">
```

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/merge-prs/merge-pr33.md
around lines 46 - 48, Remove the empty mermaid code fence and its comment
marker—specifically delete the ```mermaid code fence and the line "%% (Mermaid
optional — primary is the SVG below)" so only the provided SVG remains in the
document; ensure no leftover backticks or mermaid markers remain.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/HERMES_AGENT_E2E_TRUTH_PROOF_PLAN_2026-05-08.md (1)</summary><blockquote>

`56-56`: _⚡ Quick win_

**Pin the Docker image digest in the readiness contract.**

Line 56 uses a mutable `:latest` tag. For reproducible proofs/gates, replace it with the pinned digest already established in the baseline:

<details>
<summary>Suggested change</summary>

```diff
- Docker sandbox readiness is live: Docker daemon probe passes, the configured `ghcr.io/openhands/openhands:latest` image is present locally, network policy is `none`, and denied host paths are recorded.
+ Docker sandbox readiness is live: Docker daemon probe passes, the configured `ghcr.io/openhands/openhands@sha256:e6eed4f4d7c4a368cdbd0dc8751e6fa48340d21783addfc97714b87fbeda21fa` image is present locally, network policy is `none`, and denied host paths are recorded.
```

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/HERMES_AGENT_E2E_TRUTH_PROOF_PLAN_2026-05-08.md`
at line 56, The readiness contract currently references a mutable image tag
"ghcr.io/openhands/openhands:latest" (in the "Docker sandbox readiness" line);
replace that with the pinned image digest used in the baseline (the full sha256
digest for the openhands image) so the readiness statement becomes immutable and
reproducible—locate the "Docker sandbox readiness" sentence and swap the :latest
tag for the baseline's pinned digest (e.g.,
ghcr.io/openhands/openhands@sha256:...) so proofs/gates use the exact image.
```

</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/audit/RELEASE_DOCS_2026-05-06.md (1)</summary><blockquote>

`140-144`: _💤 Low value_

**Add language identifier to fenced code block.**

The code block at line 140 showing the merge tier structure should have a language identifier for proper syntax highlighting.




<details>
<summary>📝 Proposed fix</summary>

```diff
-```
+```text
 Tier 1 (parallel): `#53`, `#54`, `#55`, `#56`, `#57`, `#58`, `#59`, `#60`, `#61`, `#62`, `#63`, `#65`, `#67`, `#68`, `#70`
 Tier 2 (sequential): `#66` → `#69`  (app.py UNION conflict)
 Tier 3 (sequential): `#64` → `#71`  (adapters.ts UNION conflict)
 ```
```

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @03_implementation/docs/handoffs/audit/RELEASE_DOCS_2026-05-06.md around
lines 140 - 144, The fenced code block showing the merge tier structure lacks a
language identifier; update the opening fence from "" to "text" for the
block containing "Tier 1 (parallel): #53, ..." (the fenced block around the tier
list in RELEASE_DOCS_2026-05-06.md) so the snippet is recognized as plain text
and syntax highlighting/rendering works correctly; keep the content and closing
"```" unchanged.


</details>

</blockquote></details>
<details>
<summary>03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/source-os-60-apps/REGISTRY.md (1)</summary><blockquote>

`9-14`: _💤 Low value_

**Hard-coded absolute file paths may become stale.**

Lines 9-14 reference absolute Windows paths like `G:\Github\Hermes3D\...`. These paths are environment-specific and will break if:
- The repository is cloned to a different drive/directory
- The documentation is used on a different machine
- The folder structure changes

Consider using relative paths from the repository root, or noting that these are "example paths from the original authoring environment" to set reader expectations.

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/hermes3d-os-folder-index-2026-05-07/source-os-60-apps/REGISTRY.md`
around lines 9 - 14, Update REGISTRY.md to remove hard-coded absolute Windows
paths and replace them with repository-root-relative references or clearly
labeled example paths; specifically change the entries that reference the
primary YAML (`external_repos_registry.yaml`), the fallback JSON
(`SOURCE_REGISTRY_TRUTH_AUDIT.json`), the loader logic file
(`src/hermes3d/db/load_modules.py` and its symbols `_parse_registry`,
`LAUNCH_KIND_OVERRIDES`, `SOURCE_OVERRIDES`, `SECTION_TARGET_DIRS`), the schema
file (`src/hermes3d/db/schema.sql`), the API route
(`src/hermes3d/api/routes/modules.py`), and the h3dos-codex folders listing to
either use relative paths (e.g., ./03_REPO_REGISTRY/...) or prepend a clear note
like "Example path from authoring environment" so readers know these are not
portable absolute paths.
```

</details>

</blockquote></details>

</blockquote></details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment on lines +7 to +9
"required": [
"enabled"
],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Require verify when enabled is true.

At Line 7, enabled-only configs can pass without verification metadata. That undermines the “real probe metadata” contract defined in this schema.

Proposed fix
   "required": [
     "enabled"
   ],
+  "allOf": [
+    {
+      "if": {
+        "properties": { "enabled": { "const": true } },
+        "required": ["enabled"]
+      },
+      "then": {
+        "required": ["verify"]
+      }
+    }
+  ],
   "properties": {

Also applies to: 44-94

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@03_implementation/adapter_registry/schemas/blender_bridge.schema.json` around
lines 7 - 9, The schema currently allows objects with "enabled": true to omit
the associated verification metadata; update each relevant subschema (the
objects that define the "enabled" property, e.g., the top-level blender_bridge
object and the other subschemas referenced around lines 44-94) to add a JSON
Schema conditional: add an "if": {"properties": {"enabled": {"const": true}}}
and a matching "then": {"required": ["verify"]} so that when enabled is true the
"verify" property is required; apply this pattern to every subschema that
contains "enabled" to enforce the real-probe verification contract.

Comment on lines +7 to +9
"required": [
"enabled"
],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make verify mandatory at the top level.

Line 46 states this metadata is consumed by scripts/verify_modelers.py, but Lines 7-9 currently require only enabled. That permits schema-valid configs with no verify, which can break verification flows at runtime.

Suggested patch
   "required": [
-    "enabled"
+    "enabled",
+    "verify"
   ],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"required": [
"enabled"
],
"required": [
"enabled",
"verify"
],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@03_implementation/adapter_registry/schemas/build123d_worker.schema.json`
around lines 7 - 9, The schema currently only requires "enabled" at the top
level in build123d_worker.schema.json, which allows configs without the "verify"
block; update the "required" array to include "verify" so the top-level required
properties are ["enabled", "verify"] to ensure scripts/verify_modelers.py always
find verification metadata; locate the "required" array in
build123d_worker.schema.json and add "verify" to it.

Comment on lines +7 to +9
"required": [
"enabled"
],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make verify mandatory at the schema root

Line 7 only requires enabled, but this schema declares verify as core real-probe metadata (Line 46). If omitted, invalid configs can pass validation.

Suggested fix
   "required": [
-    "enabled"
+    "enabled",
+    "verify"
   ],

Also applies to: 44-48

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@03_implementation/adapter_registry/schemas/cadquery_worker.schema.json`
around lines 7 - 9, The schema currently only lists "enabled" in the root
"required" array; add "verify" to that required list so the root requires both
"enabled" and "verify" (ensuring the declared core real-probe metadata cannot be
omitted). Update the "required" array in cadquery_worker.schema.json to include
"verify" alongside "enabled" so validation fails when "verify" is missing.

Comment on lines +30 to +35
"safe_probe_args": {
"type": "array",
"items": {"type": "string"},
"default": ["help"],
"description": "Arguments used for the read-only version probe. Never include 'slice'."
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
jq -r '.properties.safe_probe_args' 03_implementation/adapter_registry/schemas/curaengine.schema.json

Repository: Ghenghis/Hermes3D

Length of output: 244


Add constraint to prevent slice from being included in safe_probe_args.

The description states "Never include 'slice'" but the schema has no mechanism to enforce this. Currently, ["slice"] would be accepted. Add a not constraint with contains to block this forbidden value:

Proposed fix
     "safe_probe_args": {
       "type": "array",
       "items": {"type": "string"},
+      "not": {
+        "contains": { "const": "slice" }
+      },
       "default": ["help"],
       "description": "Arguments used for the read-only version probe. Never include 'slice'."
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"safe_probe_args": {
"type": "array",
"items": {"type": "string"},
"default": ["help"],
"description": "Arguments used for the read-only version probe. Never include 'slice'."
}
"safe_probe_args": {
"type": "array",
"items": {"type": "string"},
"not": {
"contains": { "const": "slice" }
},
"default": ["help"],
"description": "Arguments used for the read-only version probe. Never include 'slice'."
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@03_implementation/adapter_registry/schemas/curaengine.schema.json` around
lines 30 - 35, The "safe_probe_args" array schema currently allows any strings
including the forbidden "slice"; modify the schema for safe_probe_args to add a
JSON Schema constraint that disallows arrays containing the string "slice" by
adding a "not" block with a "contains": {"const":"slice"} (and optionally a
"message" or description update); update the safe_probe_args definition (the
object named "safe_probe_args") to include this not/contains rule so any
instance that includes "slice" will be rejected.

Comment on lines +8 to +27
"required": ["name", "source_url", "install_check", "version_pattern"],
"properties": {
"name": {"type": "string", "const": "marlin"},
"source_url": {
"type": "string",
"format": "uri",
"default": "https://github.com/MarlinFirmware/Marlin.git"
},
"default_branch": {"type": "string", "default": "bugfix-2.1.x"},
"install_check": {
"type": "string",
"default": "git ls-remote --heads https://github.com/MarlinFirmware/Marlin.git",
"description": "Read-only remote probe. NEVER a flash command."
},
"version_pattern": {
"type": "string",
"default": "^[0-9a-f]{40}\\s+refs/heads/.+$"
},
"toolchain_required": {"type": "string", "const": "toolchain_avr_gcc"},
"no_flash": {"type": "boolean", "const": true}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

cat -n 03_implementation/adapter_registry/schemas/firmware_marlin.schema.json

Repository: Ghenghis/Hermes3D

Length of output: 1412


🏁 Script executed:

fd firmware.*schema.json 03_implementation/adapter_registry/schemas/

Repository: Ghenghis/Hermes3D

Length of output: 345


🏁 Script executed:

cat -n 03_implementation/adapter_registry/schemas/firmware_reprap.schema.json

Repository: Ghenghis/Hermes3D

Length of output: 1427


🏁 Script executed:

cat -n 03_implementation/adapter_registry/schemas/firmware_klipper.schema.json

Repository: Ghenghis/Hermes3D

Length of output: 1647


🏁 Script executed:

cat -n 03_implementation/adapter_registry/schemas/firmware_prusa.schema.json

Repository: Ghenghis/Hermes3D

Length of output: 1427


Add toolchain_required and no_flash to the required fields array.

These fields have fixed values via const but are optional. Descriptors can omit them and still pass validation, contradicting the source-only contract. This pattern affects all firmware schemas (Marlin, RepRap, Klipper, Prusa).

Suggested patch
-  "required": ["name", "source_url", "install_check", "version_pattern"],
+  "required": ["name", "source_url", "install_check", "version_pattern", "toolchain_required", "no_flash"],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"required": ["name", "source_url", "install_check", "version_pattern"],
"properties": {
"name": {"type": "string", "const": "marlin"},
"source_url": {
"type": "string",
"format": "uri",
"default": "https://github.com/MarlinFirmware/Marlin.git"
},
"default_branch": {"type": "string", "default": "bugfix-2.1.x"},
"install_check": {
"type": "string",
"default": "git ls-remote --heads https://github.com/MarlinFirmware/Marlin.git",
"description": "Read-only remote probe. NEVER a flash command."
},
"version_pattern": {
"type": "string",
"default": "^[0-9a-f]{40}\\s+refs/heads/.+$"
},
"toolchain_required": {"type": "string", "const": "toolchain_avr_gcc"},
"no_flash": {"type": "boolean", "const": true}
"required": ["name", "source_url", "install_check", "version_pattern", "toolchain_required", "no_flash"],
"properties": {
"name": {"type": "string", "const": "marlin"},
"source_url": {
"type": "string",
"format": "uri",
"default": "https://github.com/MarlinFirmware/Marlin.git"
},
"default_branch": {"type": "string", "default": "bugfix-2.1.x"},
"install_check": {
"type": "string",
"default": "git ls-remote --heads https://github.com/MarlinFirmware/Marlin.git",
"description": "Read-only remote probe. NEVER a flash command."
},
"version_pattern": {
"type": "string",
"default": "^[0-9a-f]{40}\\s+refs/heads/.+$"
},
"toolchain_required": {"type": "string", "const": "toolchain_avr_gcc"},
"no_flash": {"type": "boolean", "const": true}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@03_implementation/adapter_registry/schemas/firmware_marlin.schema.json`
around lines 8 - 27, Update the JSON Schema so the fixed-valued properties are
mandatory: add "toolchain_required" and "no_flash" to the schema's "required"
array (so the const-backed properties "toolchain_required" and "no_flash" in the
"properties" block must be present); apply the same change to all other firmware
schemas that define those const properties (e.g., RepRap, Klipper, Prusa) to
enforce the source-only contract consistently.

"description": "Compile-only ARM bare-metal toolchain descriptor (32-bit ARM firmwares: Klipper MCU, RepRapFirmware, Marlin STM32). NEVER used for flashing; only --version probe.",
"type": "object",
"additionalProperties": false,
"required": ["name", "source_url", "install_check", "version_pattern"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

find . -name "*toolchain_arm_none_eabi.schema.json" -type f

Repository: Ghenghis/Hermes3D

Length of output: 142


🏁 Script executed:

cat -n "03_implementation/adapter_registry/schemas/toolchain_arm_none_eabi.schema.json"

Repository: Ghenghis/Hermes3D

Length of output: 1739


Add compile_only and no_flash to the required fields to enforce the policy.

Both properties are defined with const: true (lines 27–28) and represent immutable architectural constraints. The schema description itself emphasizes this is a "Compile-only" toolchain that is "NEVER used for flashing". These fields should be required to make the descriptor contract explicit and prevent them from being accidentally omitted.

Suggested schema fix
-  "required": ["name", "source_url", "install_check", "version_pattern"],
+  "required": ["name", "source_url", "install_check", "version_pattern", "compile_only", "no_flash"],

Also applies to: 27-28

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/adapter_registry/schemas/toolchain_arm_none_eabi.schema.json`
at line 8, The schema's required array currently lists
["name","source_url","install_check","version_pattern"] but omits the immutable
flags; update the required list to also include "compile_only" and "no_flash" so
those const:true properties are enforced by the schema (ensure you modify the
"required" value in toolchain_arm_none_eabi.schema.json to include
"compile_only" and "no_flash" alongside the existing entries).

"description": "Compile-only AVR toolchain descriptor (8-bit AVR firmwares: Marlin classic, Prusa-Firmware MK3). NEVER used for flashing; only --version probe.",
"type": "object",
"additionalProperties": false,
"required": ["name", "source_url", "install_check", "version_pattern"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In JSON Schema Draft 2020-12, does a property with "const" have to be present, or must it also be listed in "required" to enforce presence?

💡 Result:

A property schema that uses "const" does not by itself make the property required/present in the containing object. To enforce that a property is present, you must list the property name in the containing object’s "required" array. Reasoning grounded in the 2020-12 spec behavior: 1) "const" is an assertion about the value at the instance location it applies to: an instance validates against "const" when its value equals the schema’s const value.[1] 2) If the containing object does not have that property, the "properties" keyword does not apply the subschema at all (there is no value at that location to validate against the "const").[2] 3) The "required" keyword is what mandates presence of properties on an object. It restricts object instances to define the given set of properties, and does not depend on whether "properties" is present.[3] So, in JSON Schema Draft 2020-12: - "properties": { "x": { "const": 5 } } enforces that if x is present, then x must be exactly 5. - It does not enforce that x must be present. - To enforce presence, you must also add "required": ["x"] at the same object level.[3] Example: { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "x": { "const": 5 } }, "required": ["x"] } With this, instances missing x fail because of "required"; instances with x must be 5 because of "const".[3][1]

Citations:


🏁 Script executed:

cat -n "03_implementation/adapter_registry/schemas/toolchain_avr_gcc.schema.json"

Repository: Ghenghis/Hermes3D

Length of output: 1627


Add compile_only and no_flash to the required fields array.

Per JSON Schema Draft 2020-12 semantics, properties with "const" do not enforce presence in the validated instance—"required" must explicitly list them. Lines 27–28 define these fields with const: true, but line 8 omits them from required, allowing instances to pass validation without these properties. This undermines the schema's contract (stated in the description) that the toolchain is compile-only and never used for flashing. Both fields must be present and enforced at validation time.

-  "required": ["name", "source_url", "install_check", "version_pattern"],
+  "required": ["name", "source_url", "install_check", "version_pattern", "compile_only", "no_flash"],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"required": ["name", "source_url", "install_check", "version_pattern"],
"required": ["name", "source_url", "install_check", "version_pattern", "compile_only", "no_flash"],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@03_implementation/adapter_registry/schemas/toolchain_avr_gcc.schema.json` at
line 8, Add "compile_only" and "no_flash" to the JSON Schema's required array so
instances must include those properties; update the required list that currently
contains ["name", "source_url", "install_check", "version_pattern"] to also
include "compile_only" and "no_flash" so the properties defined with "const":
true (compile_only and no_flash) are enforced at validation time.

Comment on lines +7 to +9
"required": [
"enabled"
],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Require verify when the worker is enabled.

At Line 7, the schema allows enabled configs without probe metadata. That can validate incomplete configs and break/skip real verification behavior.

Proposed fix
   "required": [
     "enabled"
   ],
+  "allOf": [
+    {
+      "if": {
+        "properties": { "enabled": { "const": true } },
+        "required": ["enabled"]
+      },
+      "then": {
+        "required": ["verify"]
+      }
+    }
+  ],
   "properties": {

Also applies to: 44-87

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@03_implementation/adapter_registry/schemas/trimesh_worker.schema.json` around
lines 7 - 9, The schema currently allows configs with "enabled": true but no
"verify" data; update trimesh_worker.schema.json to require "verify" whenever
"enabled" is true by adding a JSON Schema conditional (e.g., an "if":
{"properties":{"enabled":{"const":true}}}, "then": {"required":["verify"]}) to
the schema definition that contains the "enabled" property, and apply the same
conditional to the other worker config block(s) referenced (the second
definition spanning lines 44-87) so enabled workers must include the "verify"
field.

Comment on lines +80 to +86
| `HERMES3D_OPENCODE_BIN` | path | live API | present | private env (per `path_source: private_env:HERMES3D_OPENCODE_BIN`) | Resolves to `G:\Github\opencode-dev\packages\opencode\dist\opencode-windows-x64\bin\opencode.exe` |
| `OPENCODE_BIN` | path | live API | (alternate) | private env | Listed in `required_env_keys` for OpenCode |
| `HERMES3D_OPENCODE_SOURCE` | path | E2E truth proof plan | present | private env | Resolves to local OpenCode source checkout |
| `HERMES3D_OPENHANDS_BIN` | path | live API | present | private env | Resolves to `C:\Users\Admin\.local\bin\openhands.exe` |
| `OPENHANDS_BIN` | path | live API | (alternate) | private env | Listed in `required_env_keys` for OpenHands |
| `HERMES3D_OPENHANDS_SOURCE` | path | E2E truth proof plan | present | private env | Resolves to OpenHands source checkout (`G:/Github/OpenHands`) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Redact host/user-identifying runtime paths before committing this audit artifact.

The document currently publishes machine-identifying paths/topology (e.g., user profile paths and local checkout roots). Keep evidence, but replace concrete values with stable placeholders to avoid leaking environment details.

Suggested redaction style
-| `HERMES3D_OPENHANDS_BIN` | path | live API | present | private env | Resolves to `C:\Users\Admin\.local\bin\openhands.exe` |
+| `HERMES3D_OPENHANDS_BIN` | path | live API | present | private env | Resolves to `<USER_HOME>/.local/bin/openhands.exe` |

-| `HERMES_DESKTOP_CHECKOUT` | path | src/hermes3d/api/routes/desktop_updates.py | present | desktop update staging | G:/Github/apps/hermes-desktop-main |
+| `HERMES_DESKTOP_CHECKOUT` | path | src/hermes3d/api/routes/desktop_updates.py | present | desktop update staging | <WORKSPACE_ROOT>/apps/hermes-desktop-main |

Also applies to: 108-112, 131-134

🧰 Tools
🪛 LanguageTool

[uncategorized] ~80-~80: The official name of this software platform is spelled with a capital “H”.
Context: ...v:HERMES3D_OPENCODE_BIN) | Resolves to G:\Github\opencode-dev\packages\opencode\dist\ope...

(GITHUB)


[uncategorized] ~85-~85: The official name of this software platform is spelled with a capital “H”.
Context: ... Resolves to OpenHands source checkout (G:/Github/OpenHands) | --- ## 6. Sandbox / Age...

(GITHUB)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/claude-e2e-intelligence-2026-05-08/06_ENV_KEYS_AND_RUNTIME_CONFIG_MAP.md`
around lines 80 - 86, Replace all machine-identifying concrete paths in this
document with stable placeholders: e.g., change values resolving to
"G:\Github\opencode-dev\..." "C:\Users\Admin\.local\bin\..."
"G:/Github/OpenHands" to placeholders like <REPO_ROOT>/opencode/dist/...,
<USER_HOME>/.local/bin/openhands, <REPO_ROOT>/OpenHands, etc.; update the
entries for HERMES3D_OPENCODE_BIN, OPENCODE_BIN, HERMES3D_OPENCODE_SOURCE,
HERMES3D_OPENHANDS_BIN, OPENHANDS_BIN, and HERMES3D_OPENHANDS_SOURCE accordingly
and apply the same redaction pattern to the other occurrences noted (lines
108-112 and 131-134) so the file retains proof semantics but contains no
host/user-identifying paths.

Comment on lines +49 to +52
**Command:**
```bash
gh pr merge 53 54 55 56 57 58 59 60 61 62 63 65 67 68 70 --squash
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
# Verify CLI usage shape
gh pr merge --help | sed -n '1,60p'

Repository: Ghenghis/Hermes3D

Length of output: 314


🏁 Script executed:

cat 03_implementation/docs/handoffs/claude-final-audit-2026-05-06/01_PR_MERGE_MATRIX.md | head -110 | tail -65

Repository: Ghenghis/Hermes3D

Length of output: 3299


🌐 Web query:

github cli gh pr merge command syntax documentation

💡 Result:

GitHub CLI command syntax: gh pr merge Syntax - gh pr merge [ | | ] [flags] [1] Argument behavior - With no argument, the PR for the current branch is selected. [1] Common flags / merge methods - --merge: merge the commits with the base branch [1] - --rebase: rebase the commits onto the base branch [1] - --squash: squash the commits into one commit and merge into the base branch [1] Other notable flags - --admin: use administrator privileges to merge even if requirements aren’t met (and can bypass a merge queue to merge directly). [1] - --auto: enable auto-merge only after necessary requirements are met. [1] - --delete-branch: delete the local and remote branch after merge. [1] Examples (from GitHub Docs) - gh pr merge PULL-REQUEST [2] - Non-interactive squash + custom body + delete branch: gh pr merge 523 --squash --body "my squash commit" --delete-branch [2] Repo selection flag - -R, --repo <[HOST/]OWNER/REPO> selects another repository. [1][2]

Citations:


Fix invalid batch gh pr merge commands.

The gh pr merge command accepts only one PR number per invocation. Lines 51 and 106 pass multiple PR numbers to a single call, which will fail. Use a loop to merge each PR individually:

Suggested fixes
- gh pr merge 53 54 55 56 57 58 59 60 61 62 63 65 67 68 70 --squash
+ for pr in 53 54 55 56 57 58 59 60 61 62 63 65 67 68 70; do
+   gh pr merge "$pr" --squash
+ done
- gh pr merge 74 75 76 77 78 79 --squash
+ for pr in 74 75 76 77 78 79; do
+   gh pr merge "$pr" --squash
+ done
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@03_implementation/docs/handoffs/claude-final-audit-2026-05-06/01_PR_MERGE_MATRIX.md`
around lines 49 - 52, The gh pr merge invocations currently pass multiple PR
numbers to a single CLI call (e.g., the "gh pr merge" command shown with many PR
IDs), which is invalid; replace those batched calls with either individual "gh
pr merge <PR> --squash" invocations for each PR or loop over the PR ID list and
call "gh pr merge" once per PR (ensuring the "--squash" flag is preserved) so
each PR number is merged in its own CLI invocation.

@Ghenghis
Ghenghis changed the base branch from develop to feat/hermes3d-7-complete-gui-repo-wiring May 8, 2026 23:32
@Ghenghis
Ghenghis merged commit 72e5914 into feat/hermes3d-7-complete-gui-repo-wiring May 9, 2026
1 check passed
@Ghenghis
Ghenghis deleted the claude24/i10-perf-shell branch May 9, 2026 07:08
Ghenghis added a commit that referenced this pull request May 10, 2026
* docs(contract): sync Hermes3D completion roadmap and Claude handoffs

WIP checkpoint per GITHUB_SYNC_PLAN_2026-05-06: contract docs, roadmap,
and 20-agent handoff before Claude lanes branch off this baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(api): add live Hermes3D backend routes and proof services

WIP checkpoint per GITHUB_SYNC_PLAN_2026-05-06: API routes, services,
db schema/init, core orchestration + slicer/printer adapters baseline
for the 20-agent completion lanes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(ui): wire live Hermes3D tabs and remove mock UX

WIP checkpoint per GITHUB_SYNC_PLAN_2026-05-06: live tab shells
(Source OS, Settings, Agents, Observe, Roadmap, Plugins, Jobs,
Artifacts, Approvals, Voice, Learning, Autopilot, Design, 3D Generation,
Printers), live API adapters, ResizablePane/AppShell layout, and
removal of mock data + retired tabs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(source-os): add adapter schemas, source audits, and runtime proof

WIP checkpoint per GITHUB_SYNC_PLAN_2026-05-06: 31 adapter_registry
JSON schemas (slicers/modelers/print-farm/gen3D/firmware), source-app
audit scripts, and proof artifacts (CLI surface, runtime action plan,
local tooling audit) backing the Source OS lane.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(e2e): add live GUI and no-fake proof coverage

WIP checkpoint per GITHUB_SYNC_PLAN_2026-05-06: Playwright e2e config
and live-gui spec, runtime-port + GUI-API + e2e-stack starters; retire
visual specs replaced by the live e2e suite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ci(fix): extend ui-ci.yml PR trigger to feat/** branches (TS7026 root cause) (#80)

* ci(fix): extend ui-ci.yml PR trigger to feat/** branches

`pull_request.branches` previously only listed `[main, develop]`.
Lane PRs target `feat/hermes3d-7-complete-gui-repo-wiring`, so
`npm ci` + `tsc --noEmit` (Layer D2) never ran for them.

Adding `feat/**` ensures the strict lint gate fires on every lane
PR, surfacing the pre-existing TS7026/TS7006 JSX.IntrinsicElements
regression (caused by missing `node_modules` in fresh worktrees)
rather than silently passing.

Root cause confirmed: `npm run lint` returns 0 errors after
`npm install`; tsconfig.json and @types/react are correct.
The regression only appears without node_modules.

Task: a2a_1778114702912_1ac758ea

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* ci: install API deps for UI workflow

* fix: seed provider module targets before providers

* fix: stabilize UI final truth gate

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(roadmap): sync Hermes3D state with live baseline (H3D-CLAUDE-DOCS-PROOF) (#53)

Add Claude-authored docs companion and proof for the 20-Agent Completion
Contract Lane 18. Records the 5-commit shared baseline, 16-tab inventory
from routes.tsx, and the live S1/T1/V400 printer policy. README gains
pointers to the operator GUI roadmap and the contract handoff. ROADMAP.md
intentionally not edited because of an active codex-master Hermes lock.

Hermes evidence chain: PASS
Task ID: H3D-CLAUDE-DOCS-PROOF
hermes_run_gate: PASS

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(app-shell): finish resizable panels + density + Simple/Main parity (H3D-CLAUDE-APP-SHELL) (#54)

ResizablePane hardening:
 - Escape during drag restores pre-drag width
 - touchAction: none on the handle so drag works on touch devices
 - Re-clamp persisted width when min/max bounds change at runtime
 - SSR-safe localStorage write guard

Lane scope was bounded by Codex-master locks on AppShell, Sidebar, TopBar,
Panel, globals.css, tailwind.config.ts — those files were not contended.
DockModeToggle left unchanged: TopBar already owns the live Simple/Main
toggle via setUiMode and coupling DockModeToggle would break Phase 2 panel
docking semantics.

Hermes evidence chain: PASS
Task ID: H3D-CLAUDE-APP-SHELL
hermes_run_gate: PASS

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(e2e): add tab-specific Playwright specs (H3D-CLAUDE-PLAYWRIGHT) (#55)

Adds per-tab Playwright e2e specs for all 16 primary tabs and Roadmap,
each asserting truthful root mount, no forbidden mock/placeholder text
in production surfaces, and a clean console. Network calls are stubbed
at the GUI-API boundary; printers.spec.ts hard-aborts any request that
would reach live S1/T1/V400 operator IPs.

Hermes Task ID: H3D-CLAUDE-PLAYWRIGHT
Hermes evidence: ev_9d0e995e54bbac18

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(security): MCP boundary + prompt-injection + secret-redaction audit (H3D-CLAUDE-SECURITY-MCP) (#56)

Lane 19 of the Hermes3D 20-Agent Completion Contract. Adds READ-ONLY
behavioural tests over the in-house OWASP LLM-01 prompt-injection scanner
(commit 0c9b6d9), the secret-redaction surface in services/local_state.py
+ services/module_runtime.py + services/agent_runtime.py, the canonical
user-supplied-path validators in services/code_history.py, and the
MCP/tool-boundary policy gates that protect printers and the agent
runtime URL.

New files (lane-owned only):
- 03_implementation/tests/security/__init__.py
- 03_implementation/tests/security/conftest.py
- 03_implementation/tests/security/test_prompt_injection.py
- 03_implementation/tests/security/test_secret_redaction.py
- 03_implementation/tests/security/test_path_traversal.py
- 03_implementation/tests/security/test_mcp_boundary.py
- 03_implementation/proof/security/SECURITY_AUDIT_2026-05-06.json
- 03_implementation/docs/security/MCP_BOUNDARY_NOTES.md

Vectors covered (full list in SECURITY_AUDIT_2026-05-06.json):
- OWASP LLM-01 indirect injection, ChatML/Llama control tokens,
  RCE-shaped tool-poisoning (curl|sh, wget|bash, iex/iwr), prompt-leak
  variants, jailbreak personas (DAN, devmode, ignore-safety,
  no-restrictions, pretend-unrestricted), and unicode-control no-crash
  guarantees.
- LLM-02 (light): execute-following + base64 payload framing.
- LLM-06: AST scan over services/*.py rejects raw secret-shaped
  literals (sk-, ghp_, AKIA, bearer, xoxb-) in source AND in any
  logging emitter call site; pins module_runtime._redact_text on
  every subprocess->output_head path; pins agent_runtime never logs
  private_values / private_env() / env_value() return values.
- Path traversal: 8 explicit-reject vectors (../etc/passwd, drive
  letters, null-byte injection, empty path), plus the documented
  coercive cases (/etc/passwd and //attacker.example/share/x are
  re-rooted into PROJECT_ROOT — informational, no escape possible).
- MCP boundary: build-plate-clearance gate, FLSUN S1 read-only lock,
  trusted_runtime_url rejects non-private hosts / credentials /
  query / fragment / wrong scheme / self-bridge ports 8765+8642,
  scanner ships >=15 OWASP + >=10 in-house rules, fail_threshold
  knob, redacted-text logging sink, secret-storage convention pinned
  to G:\private\.env (outside repo).

Findings (logged, NOT silently fixed; surfaced via xfail strict=True
so they fail loudly when patched upstream):

- FINDING-INJ-1 (medium, owner = core/security ruleset lane):
  LLM01-LEAK-VERBATIM regex misses reverse word order
  `the prompt verbatim`. Suggested fix: anchor on `verbatim`
  independent of word order or add LLM01-LEAK-VERBATIM-REV.

- FINDING-INJ-2 (medium, owner = core/security ruleset lane):
  Zero-width-space (U+200B) injected in `ignore` bypasses
  LLM01-IGN-PREV; `dump` is missing from leak alternation.
  Suggested fix: pre-normalise zero-width / bidi control chars
  before matching; extend LLM01-LEAK-SYSPROMPT verb alternation.

- FINDING-PATH-1 (low, informational, owner = Codex / code_history
  lane): `_resolve_project_subpath` re-roots `/etc/passwd` and
  `//attacker.example/share/x` into PROJECT_ROOT rather than
  rejecting. SAFE (no escape; `relative_to(PROJECT_ROOT)` enforces
  containment) but contract is coercive, not rejective.

Required gates: PASS
- python -m py_compile services/*.py routes/*.py: PASS
- scan_active_ui_no_fake.py: PASS
- pytest 03_implementation/tests/security/: 78 passed, 2 xfailed
- npm run lint: PASS

Hermes evidence: ev_cfb93a332dd6918a (ledger entry hash chain
extended). Lock owner: claude-security-mcp-19. No files outside
03_implementation/{tests,proof,docs}/security/ were modified.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(source-gen3d): real source+runtime verifiers for ComfyUI/TRELLIS/Hunyuan3D/TripoSR (H3D-CLAUDE-SOURCE-GEN3D) (#57)

Adds adapter_registry/scripts/tests for the five generative-3D providers
without performing any heavy operation:

* schemas: extend comfyui/trellis2/hunyuan3d/triposr/bambustudio_bridge
  with source_repo, pip_package, weights_cache_dirs (all backward compatible).
* scripts/verify_gen3d.py: stdlib + subprocess only.
  - git ls-remote --heads (no clone), 5s timeout.
  - pip show <pkg> (no install), 5s timeout.
  - Boolean cache-presence for ~/.cache/huggingface and similar.
  - Bambu Studio: launcher executable presence only (no launch).
* proof/GEN3D_VERIFY_2026-05-06.json: 5/5 repos reachable;
  Bambu Studio launcher present; comfyui/trellis2/hunyuan3d/triposr
  honest "not installed" (no fabrication, no downloads).
* tests/source_lab/test_gen3d.py: pytest validates proof shape, policy
  invariants, full provider coverage, and reachability honesty.

Hermes evidence chain: PASS
Task ID: a2a_1778106411818_946d5ec0
Lane: H3D-CLAUDE-SOURCE-GEN3D
hermes_run_gate: verify_gen3d, pytest test_gen3d, py_compile, scan_active_ui_no_fake

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(source-firmware): firmware toolchain proof gates, no-flash safety (H3D-CLAUDE-SOURCE-FIRMWARE) (#58)

- Add JSON schemas for Klipper, Marlin, RepRapFirmware, Prusa firmware sources
- Add JSON schemas for arm-none-eabi-gcc and avr-gcc toolchains
- Add verify_firmware.py: probes toolchain availability (--version only) and
  firmware source reachability (git ls-remote only); NEVER flashes, NEVER
  opens serial/USB to printer boards
- Add test_firmware.py: pytest suite asserting schema validity, no-flash policy,
  verifier source integrity, and no-network proof generation
- Add FIRMWARE_VERIFY_2026-05-06.json: proof artifact (all 4 firmware sources
  reachable; toolchains absent on this host — honestly recorded)

Lane: H3D-CLAUDE-SOURCE-FIRMWARE
Owner: claude-source-firmware-05
Hermes evidence chain: PASS

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(source-printfarm): read-only Moonraker/Klipper/OctoPrint verifiers (H3D-CLAUDE-SOURCE-PRINTFARM) (#59)

- verify_printfarm.py: HTTP GET-only probes for Moonraker (T1-a, T1-b, V400),
  OctoPrint, Fluidd, Mainsail, FDM Monster, KlipperScreen, Printrun.
  FLSUN S1 camera skipped per lane policy. Honest "unreachable" for all
  localhost services (not running on this host). 3/3 Moonraker printers
  reached; V400 version: v0.7.1-586-gbb526e0-dirty.
- test_printfarm.py: pytest suite asserting proof JSON shape, policy
  invariants, GET-only constraint, S1 never-probed, and summary consistency.
- PRINTFARM_VERIFY_2026-05-06.json: proof artifact with live results.
- adapter_registry/schemas/moonraker_api.schema.json: JSON Schema for
  read-only Moonraker HTTP adapter (GET-only, forbidden endpoints listed).
- adapter_registry/schemas/klipper_service.schema.json: JSON Schema for
  Klipper service adapter (systemctl/moonraker-proxy, no G-code ever).

Hermes evidence chain: PASS
Task ID: H3D-CLAUDE-SOURCE-PRINTFARM

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(source-modelers): real verifiers for Blender/OpenSCAD/FreeCAD/CadQuery/build123d/trimesh (H3D-CLAUDE-SOURCE-MODELERS) (#60)

- 9 adapter schemas with real verify blocks (version_probe, install_check, runtime_check)
- scripts/verify_modelers.py: live CLI + pip-show probes, no fake/mock gates
- tests/source_lab/test_modelers.py: pytest contract validation for proof JSON
- proof/MODELERS_VERIFY_2026-05-06.json: honest results — found: blender, openscad, trimesh; not_found: freecad, cadquery, build123d

Lane: H3D-CLAUDE-SOURCE-MODELERS

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(artifacts): proof bundle index + artifact discovery API (H3D-CLAUDE-ARTIFACTS-PROOF) (#61)

- artifacts.py: add GET /api/artifacts/list (scans proof/ dir live, no hardcoded data)
  and GET /api/artifacts/proof/{filename} (serves proof files with path-traversal guard)
- PROOF_MANIFEST_2026-05-06.json: real manifest of all 14 proof files in proof/
  (generated by scanning directory, includes sizes, timestamps, lane IDs)
- Artifacts.tsx: add Proof Bundles panel calling /api/artifacts/list; displays
  all proof files with View links; no mock data

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(learning-autopilot): truthful idle work kinds + real backend state (H3D-CLAUDE-LEARNING-AUTOPILOT) (#62)

- AutopilotConsole: remove hardcoded fake status values (Loop: on, Window: 8h, Risk: low)
  that were not connected to any backend; replace with props-driven readyCount/totalChecks
  that drive honest live/unavailable/blocked state display
- AutopilotTab (existing): already calls /api/autopilot/readiness + /api/autopilot/guardrails
  for real backend state - no fake activation
- LearningTab (existing): all idle work kinds call real endpoints with honest blocked state:
  createIdleCandidate → POST /api/learning/idle-workbench/candidates
  runIdleCandidate → POST /api/learning/idle-workbench/candidates/{id}/run
  requestIdleCandidateReview → POST /api/learning/idle-workbench/candidates/{id}/request-review
  decideIdleCandidate → POST /api/learning/idle-workbench/candidates/{id}/decision
- Backend learning.py: run endpoint returns accepted:false + reason when runtime not configured
- Backend autopilot.py: next-gate returns 409 with failing check detail when not all ready
- Pre-existing TS7026 regression: 0 errors (lint clean)
- Python compile: learning.py OK, autopilot.py OK

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(source-slicers): real CLI verifiers for slicers (H3D-CLAUDE-SOURCE-SLICERS) (#63)

* feat(design): real CAD template gallery + provider health checks (H3D-CLAUDE-DESIGN) (#65)

- backend: add GET /api/design/templates — discovers templates from real
  importable executor modules (hermes3d.core.design.*), reports
  executor_available + missing_deps from live importlib checks
- backend: add GET /api/design/providers — probes OpenSCAD, Blender,
  CadQuery, trimesh, manifold3d, FreeCAD via shutil.which + importlib;
  no cached stubs, no fake version strings
- UI: Design.tsx pulls templates and providers from real backend endpoints;
  template select populated from /api/design/templates (disabled if
  executor unavailable); provider health panel shows live probe results;
  template gallery shows preview-not-available for all templates (no
  renderer wired); no hardcoded "Generated successfully" messages
- tests: add 04_testing/pytest/unit/test_design_providers.py — 18 tests
  covering _discover_templates, _probe_providers, _probe_cli_provider,
  _probe_python_provider; trimesh/manifold3d tests assert against live
  importlib.util.find_spec to prevent divergence from reality

Pre-existing TS7026 errors in other tabs (not Design.tsx): noted in PR, not
fixed in this lane per cross-lane separation rules.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(observe): camera grid + S1 90deg + refresh reliability + V400 status (H3D-CLAUDE-OBSERVE) (#67)

- Backend: add GET /api/observe/status with per-camera health, response_ms, estimated_fps,
  and read_only flag (S1 at 192.168.0.12 is flagged read-only; never receives control cmds)
- Backend: refactor _probe_camera into _probe_camera_timed for fps estimation;
  update camera_health endpoint to return response_ms + estimated_fps
- Frontend types: add CameraStatus + ObserveStatusResponse interfaces to observe.ts
- Observe.tsx: exponential backoff retry on feed error (1s base → 30s max);
  feedState gains 'reconnecting' state with spinner overlay instead of broken image;
  auto-refresh interval selector (off / 3s / 5s / 10s / 30s) polls /api/observe/status;
  online/offline summary badge in header; Refresh all button triggers both feed + status fetch;
  V400 per-card online/offline chip + fps indicator from status API;
  S1 defaults to 90deg rotation (backend + defaultViewSettings already enforced)
- ObserveConsole.tsx: replace hardcoded mock camera list with live /api/observe/status polling
  every 5s; shows read_only badge on S1, fps estimate per camera, online/offline with ping ms

Camera safety: S1 (192.168.0.12) is camera/read-only throughout; no move/upload/print/test
commands are issued from Observe tab or status endpoint.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(jobs): policy-gated repair/retry/rollback + proof state (H3D-CLAUDE-JOBS) (#68)

- Add _check_printer_policy() to jobs.py enforcing three ordered gates:
  1. S1 hard lock (192.168.0.12 / flsun-s1 always rejected, HTTP 423)
  2. PRINTER_WRITE_DENIED: printer must be write_enabled or in WRITE_ALLOWED_PRINTERS (HTTP 423)
  3. PRINTER_IDLE gate: printer state must be standby/complete/ready/error before retry/repair/rollback (HTTP 409)
- apply_repair, retry_job, rollback_job all call _check_printer_policy() before mutating any state
- propose_repair calls check_s1_lock() (read-only planning step, no printer movement)
- Every policy block records a proof event in proof_events table with printer_id, job_id, reason
- Jobs.tsx already correct: real endpoints, state machine, proof event IDs displayed — no fake messages
- Add 04_testing/pytest/unit/test_jobs_policy.py: 37 tests covering S1 lock, read-only policy, PRINTER_IDLE gate, no-printer pass-through, write-enabled idle pass-through, proof event DB writes

NEVER sends job commands to moving printers. S1 (192.168.0.12) never a job target.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(gen3d): real provider readiness + proof-backed local templates (H3D-CLAUDE-GEN3D) (#70)

- backend: add GET /api/gen3d/providers — reads Lane 04 GEN3D_VERIFY_2026-05-06.json
  proof + live port probe for ComfyUI; returns installed/repo_reachable/weights_present
  for comfyui, trellis2, hunyuan3d, triposr, bambustudio_bridge; no fake readiness
- backend: add GET /api/gen3d/templates — discovers local templates (calibration_cube via
  trimesh, no provider needed) + provider-backed templates from adapter_registry schemas;
  schema_present field reflects real file existence
- UI: provider status panel now shows 3D generation provider readiness (from
  /api/gen3d/providers) with readiness badges sourced from Lane 04 proof data
- UI: local template gallery (from /api/gen3d/templates) — cards show source, outputs,
  required provider; selecting provider-backed template with unavailable provider shows
  "Provider not available" on Generate with a proof event emitted
- tests: add test_gen3d_routes.py with 14 unit tests covering both new endpoints

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(source-ui): SourceOS CLI readiness + proof panel + no-cutoff layout (H3D-CLAUDE-SOURCE-UI) (#66)

- Add CliReadinessPanel component: collapsible section showing CLI readiness
  for all 5 tool categories (slicers, modelers, print_farm, firmware, gen3d)
  with per-key-tool status badges (Verified CLI / Detected / Source Ready /
  Not Installed / Unavailable). Data comes from /api/sources/readiness.
- Add ProofArtifactPanel component: collapsible section with links to
  /api/artifacts and per-category artifact queries, plus proof file listing.
- CliReadinessPanel and ProofArtifactPanel use overflow-y: auto with maxHeight
  to ensure no content cutoff — all content is scrollable.
- Create 03_implementation/src/hermes3d/api/routes/source_os.py:
  GET /api/sources/readiness reads proof JSON files (LOCAL_TOOLING_AUDIT,
  SOURCE_APP_CLI_AGENT_READINESS_AUDIT, SOURCE_APP_CLI_SURFACE_AUDIT) and
  returns aggregated readiness per category with key tool details.
- Wire source_os router into hermes3d/api/app.py.
- No hardcoded readiness states — all from proof JSON files.
- tsc --noEmit: PASS (zero errors in owned files; pre-existing TS7026 regression
  in other src/*.tsx files predates this contract).
- py_compile source_os.py: PASS.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(settings-plugins): update center + provider health + failsafe rollback (H3D-CLAUDE-SETTINGS-PLUGINS) (#69)

- Add GET /api/settings/update-center: real component versions, Velopack readiness, live provider probes, rollback availability
- Add POST /api/settings/update-center/rollback/{component}: surfaces rollback for proof-gated flow
- Register update_center router in app.py
- New UpdateCenterSubtab.tsx: live update center with failsafe rollback cards
- New PluginRollbackPanel.tsx: per-plugin health + deactivate/rollback action
- SettingsPage.tsx: add Update Center subtab wired to UpdateCenterSubtab
- AboutSubtab.tsx: fetch real versions from backend, removed hardcoded VERSION constant

Pre-existing TS errors in other files not introduced here. tsc passes clean for all touched files.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(voice): transcript history + playback controls + proof review (H3D-CLAUDE-VOICE) (#64)

- Backend: add GET /api/voice/transcripts, GET /api/voice/recordings/{id},
  GET /api/voice/proof-events to voice.py; recordings served as binary
  audio from proof_events table; no API key in any URL
- Types: add VoiceTranscript and VoiceProofEvent to voice.ts
- Adapters: add getVoiceTranscripts, getVoiceProofEvents, getVoiceRecordingUrl
  to AdapterAPI interface + live implementations + parse helpers
- UI: Voice.tsx gains three-tab layout (Voice Browser / Transcript History /
  Proof Review); playback routed through backend only (new Audio(backendUrl)),
  no device access from frontend; honest empty states when no data yet

Gates: python -m py_compile OK; tsc --noEmit 0 errors

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(printers): onboarding wizard + Moonraker probe + S1 camera-only lock (H3D-CLAUDE-PRINTERS) (#71)

- Add 5-step printer onboarding wizard to PrintersTab:
  Step 1: Enter IP + connection type (Moonraker/OctoPrint/direct)
  Step 2: Auto-probe via GET /api/printers/probe (read-only, shows version/firmware/bed size)
  Step 3: Set camera URL with MJPEG validation
  Step 4: Confirm + save profile with write-enable toggle
  Step 5: Done / refresh fleet

- S1 (192.168.0.12) is LOCKED in the wizard: shows 'Camera only — cannot add as
  print target' before any network call is made; frontend enforces CAMERA_ONLY_IPS set

- Add GET /api/printers/probe backend endpoint:
  Read-only: calls only GET /server/info and optional /printer/objects/query
  Never sends GCode, commands, or mutations
  Returns: Moonraker version, klippy_state, bed size from fleet profile

- Add POST /api/printers/validate-camera backend endpoint:
  Read-only: HEAD request only, checks Content-Type for multipart/x-mixed-replace
  Returns: {ok, content_type, is_mjpeg, http_status}

- Add CAMERA_ONLY_IPS frozenset constant in printers.py (single source of truth):
  Any attempt to add 192.168.0.12 as a print target returns 403 CAMERA_ONLY_IP
  Covers: probe endpoint, onboard URL validation, printer ID validation

- Add test_printer_policy.py (16 tests, all passing):
  - S1 IP blocked in onboard URL validation (403 CAMERA_ONLY_IP)
  - S1 aliases blocked in printer ID validation (423)
  - Probe endpoint returns 403 for S1 IP
  - Probe is read-only: send_gcode/upload_gcode/start_print never called
  - Camera validate uses HEAD request only
  - MJPEG detection verified
  - TestClient route integration tests

- TypeScript: tsc --noEmit passes cleanly (0 errors in owned files)
- Python: py_compile passes for printers.py and test_printer_policy.py
- Pre-existing TS7026 errors in other src/*.tsx files are unrelated to this lane

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(integration): 20-agent completion integration report (H3D-CLAUDE-FINAL-INTEGRATOR) (#72)

All 19 lane PRs (#53-#71) are OPEN/MERGEABLE with CodeRabbit SUCCESS and
Hermes evidence chain PASS. Two cross-lane file conflicts identified:

- app.py: PRs #66 + #69 both add a router (additive, UNION merge)
- adapters.ts / adapters.live.ts: PRs #64 + #71 both add methods (additive, UNION merge)

Merge order: Tier-1 (15 PRs in parallel) → Tier-2 (#66→#69) → Tier-3 (#64→#71).
Pre-existing JSX TS7026/TS7006 regression (~57 files) flagged as HIGH-priority fix-PR
needed before release.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* audit(runtime): proof files + verifier scripts + route truth verification (#74)

Verifies all 6 proof JSON files are real (not hand-crafted), all 4 verifier
scripts use genuine subprocess/filesystem probes, and all 7 API routes have
real implementations. All syntax checks pass. No blockers found.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* audit(merge): PR base + conflict cluster + silent drop verification (H3D-CLAUDE-POLISH-MERGE-2026-05-06) (#75)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* audit(security): secret scan + path traversal + shell audit (H3D-CLAUDE-POLISH-AGENT-MCP-PROOF-2026-05-06) (#76)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* audit(safety): S1 lock + printer policy + GCode scan verification (#77)

53/53 policy tests pass. S1 (192.168.0.12) blocked before every network call.
Zero GCode keywords in probe/read routes. Zero bypass paths found. Camera controls
are CSS-only display transforms with no hardware commands.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* audit(docs): PR body completeness + ROADMAP truth + merge plan verification (H3D-CLAUDE-POLISH-RELEASE-DOCS-2026-05-06) (#78)

- Audited all 20 PR bodies (#53-#72): all have evidence chain, task ID, and gates
- PR #53 missing formal files table (prose description present); PR #64 minimal body
- TS7026 blocker documented in PR #72; absent from ROADMAP.md (codex-master locked)
- README "77 of 79" claim is stale relative to feature branch (update post-merge)
- Merge Tier 1/2/3 structure is correct; PR #72 needs explicit Tier 4 slot in plan
- No PRs accidentally merged; all 20 lane PRs remain open

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* audit(nofake-ui): 0 violations — no-fake scan + 33 buttons wired + 0 lane TS errors (H3D-CLAUDE-POLISH-NOFAKE-UI-2026-05-06) (#79)

* docs(handoff): final Codex takeover bundle — 9 audit/merge/lock files (#81)

Closes the Claude 20-agent + 6-audit-agent run. Contains:

  00_EXECUTIVE_TAKEOVER_SUMMARY.md  — 1-page status for Codex
  01_PR_MERGE_MATRIX.md            — exact tier merge order for #53-#80
  02_OPEN_BLOCKERS_AND_FIX_QUEUE.md — 0 code blockers, 4 low/info doc gaps
  03_LOCKS_WORKTREES_AND_BRANCHES.md — 28 Claude locks released, 28 worktrees
  04_RUNTIME_TRUTH_AND_NO_FAKE_AUDIT.md — Audit 2+3: 0 fake violations
  05_PRINTER_SAFETY_AND_PHYSICAL_IO_AUDIT.md — Audit 4: S1 camera-only PASS
  06_SECURITY_MCP_AND_AGENT_ACCESS_AUDIT.md — Audit 5: no traversal/secret leaks
  07_ARCHITECTURE_AND_FLOW_DIAGRAMS.md — Mermaid diagrams for all flows
  08_FINAL_CLAUDE_RELEASE_NOTE.md  — final PR list + lock state + Codex next steps

All 28 Claude-owned Hermes locks released.
All 20 lane PRs (#53-#72) and 6 audit PRs (#74-#79) open CLEAN.
TS7026 fix PR #80 open (CI running).
Hermes task: a2a_1778115796454_685e7b14

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ui): clear post-merge npm audit vulnerabilities (#82)

* fix(ui): clear npm audit vulnerabilities

* fix(ui): clean post-merge browser gates

* fix: align observe refresh button contract

* [codex] add MCP-locked Hermes Agent code operator (#73)

* feat(agents): add MCP-locked code operator lane

* docs(handoff): add Claude final audit takeover contract

* fix(agents): harden code operator lane

* docs(handoff): Hermes3D OS folder index 2026-05-07 — 86 markdowns w/ inline SVG (#86)

Comprehensive index of every Hermes3D OS folder in G:\Github\ modified
between 2026-04-27 and 2026-05-07. Authored by 13 parallel sub-agents
under task a2a_1778147261453_661b606f.

Structure (12 categories, 60 included folders, 7 excluded):
  00_INDEX.md            -- master nav + topology SVG
  01_TAXONOMY.md         -- classification rules
  02_EXCLUSIONS.md       -- 7 folders intentionally excluded + reasons
  apps-vendored/         -- 7 vendored apps (~1.08 GB) + README
  core-repos/            -- 5 core H3D repos + README
  agent-infra/           -- 5 hermes-agent / MCP infra + README
  hp-protocol/           -- 9 HP P0/P1 hardening folders + README
  hermesproof/           -- 6 HermesProof component sandboxes + README
  source-os-60-apps/     -- canonical 60-app registry + treemap SVG
  h3dos-wire-tasks/      -- 18 single-button UI wire lanes + README
  h3dos-codex-tasks/     -- 5 Codex app integration lanes + README
  merge-prs/             -- 4 cascade-merge worktrees + README
  h3d-enhancements/      -- 7 H3D enhancement branches + README
  worktree-collections/  -- 3 umbrellas (49 sub-worktrees) + README
  research/              -- _research scratchpad + README

Each per-folder markdown includes: H1 title, purpose, status,
branch+commit, key files, relationships, and inline hand-written
SVG (400-900 px). Category READMEs add master inventory tables and
larger SVGs (700-900 px).

Excluded (7): kilocode-Azure2, contract-kit-v17 (3 variants),
TRELLIS.2, Agentic-Modeler, _repo_rescue_evidence -- documented
in 02_EXCLUSIONS.md with reasoning.

Hermes evidence chain: PASS

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(queue): recover closed stacked PR work (#105)

* feat(agents): add MCP-locked code operator lane

* docs(handoff): add Claude final audit takeover contract

* fix(agents): harden code operator lane

* feat(agents): add proof-gated git shipping lane

* feat(agents): add provider team assignment lane

* feat(agents): add provider execution artifacts

* feat(source-os): add runner contract matrix

* feat(source-os): register python cad verifier family

* feat(source-os): correct slicer runner truth

* feat(source-os): add print farm health verifiers

* feat(source-os): add service web health verifiers

* feat(source-os): add safe service start-runner preflights

* feat(source-os): supervise service runner starts

* test(unit): remove live fleet timeout from offline tests

* feat(source-os): add firmware source inventory verifiers

* feat(accel): add rust metadata proof worker

* feat(source): add read-only runner smoke contracts

* feat(source): add executable path runner smoke

* feat(source): add python import repair preflights

* feat(source): add slicer cli config preflights

* feat(source): add npm package metadata preflight

* docs(agents): define e2e proof plan

* feat(agents): add e2e workbench

* feat(agents): add provider smoke and reviewed ship lane (#104)

* feat(agents): add provider smoke and reviewed ship lane

* fix(agents): prove live runtime freshness

* feat(agents): add cli runner contracts

* fix(agents): require live provider smoke proof

* docs(handoff): Claude 20+ agent E2E completion intelligence bundle 2026-05-08 (#106)

Read-only intelligence sweep produced per PR 104's Claude 20+ Agent E2E
Completion Intelligence Contract. 12 markdown deliverables under
03_implementation/docs/handoffs/claude-e2e-intelligence-2026-05-08/
covering: executive map, G:/Github folder ecosystem audit, stale
code/branch map, Hermes Agent runtime gap map, Source OS 60-app
completion map, tab-by-tab UI no-fake audit, env-key/runtime config map,
test gates + proof matrix, PR + merge queue, Codex next 50 tasks, 6
Mermaid diagrams, and final Claude note.

Live truth captured at 2026-05-08 17:25Z from API on branch
codex/provider-smoke-workbench commit 43d8205: 220 routes, all 10 Agent
Workbench routes present, 60 Source OS apps (7 agent_cli_ready, 24
runner_gaps), 81 active UI files clean (no-fake scan PASS), 25 open PRs
all CLEAN/CodeRabbit-SUCCESS. Hard blocker: MiniMax + DeepSeek HTTP 401
on G:/private/.env keys (Tier 0 user action; Codex chain not blocked).

No source code edited. No PRs merged. No Codex-owned locks released. 12
hermes3d-locks acquired by claude-e2e-intel-aggregator (taskId
claude-e2e-intel-2026-05-08) for the markdown bundle; released after PR
open per contract.

Hermes evidence chain: kickoff ev_b6e233d4ac466056

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(agents): prove provider env aliases (#107)

* docs(handoff): prepare Claude 24-agent completion contract (#108)

* proof(I14): update no-fake sweep 2026-05-08 — 81 files, PASS (#116)

Active UI no-fake scan re-run on 2026-05-08:
- 81 production files walked from App.tsx entry point
- 0 findings (no mock/fake/simulated markers in string literals)
- No data/mock imports in active graph
- 15 orphaned/unwalked files separately verified clean
- scan_active_ui_no_fake.py requires no changes

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(I8): printer safety — S1 camera-lock tests, T1/V400 policy gates (#111)

Adds 25 new test cases to test_printer_policy.py closing the critical safety
gap where S1 (192.168.0.12) action endpoints (move, test, upload, upload-gcode)
had no direct hard-lock assertions. New TestS1ActionHardLock class proves 423
PRINTER_LOCKED fires before any MoonrakerClient I/O for all four action routes,
across all S1 aliases. TestT1V400PolicyGates confirms write-allowed printers are
not misclassified as S1 and pass the lock gate. 78/78 tests pass.

Task: H3D-CLAUDE24-I8-PRINTER-SAFETY

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(I4): add runner_family to all 60 runner-contracts + blocked_reason for BLOCKED rows (#119)

- Add _contract_runner_family() mapping runner_status → valid family string
- Add runner_family field to module_runner_contract() return dict (was absent,
  causing all 60 /runner-contracts rows to have FIELD_MISSING)
- Fix blocked_reason for slic3r and superslicer (runner_status=blocked):
  previously suppressed by cli_install_config_available=True condition; now
  always set when runner_status==blocked regardless of preflight runner
- Valid families emitted: agent_cli_ready, read_only_runner, executable_path,
  python_import_repair, cli_install_config, npm_package_preflight,
  desktop_app_runner_gap, gpu_worker_runner_gap, runtime_repair_required,
  source_reference_only, blocked, metadata_ready_needs_runner
- 113 pytest tests pass; only locked file modified

Task: H3D-CLAUDE24-I4-SOURCEOS-CORE
Hermes evidence chain: PASS
Gates run: python -m py_compile (both files), pytest 113 passed
Rows fixed (null→known runner_family): 60

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(I1): provider endpoint/model config audit — MiniMax+DeepSeek smoke (#112)

Audit confirmed both providers have correct code configuration:
- MiniMax: /v1/chat/completions, Bearer auth, MiniMax-M2.7 — all correct
- DeepSeek: /chat/completions, Bearer auth, deepseek-v4-pro — all correct
HTTP 401 on both is a pure API key issue (invalid/expired keys in G:\private\.env).

Added inline comments to PROVIDER_DEFAULT_BASE_URLS documenting the verified
endpoint/auth/model contract and the exact user action needed to resolve 401s.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(I2): wire E2E code loop — patch-apply, gate-run, branch-commit-pr chain (#118)

- audit confirmed: apply_reviewed_patch_proposal, run_mcp_gate,
  git_commit_owned_files, git_push_current_branch, git_open_pull_request,
  restore_snapshot all fully implemented (no stubs)
- wiring gap found and fixed: no GET /e2e/jobs endpoint existed to list
  job states — added list_e2e_jobs() to code_history.py and the
  GET /api/code-operator/e2e/jobs route to code_operator.py
- new GET route queries proof_events for code_e2e/code_patch/code_git
  event types and returns job state legend for E2E loop operators
- expanded test_code_operator_routes_are_registered to assert all 7
  E2E chain routes are wired: apply-reviewed, gates/run, git/branch,
  git/commit-owned, git/push, git/pr, e2e/jobs GET
- added test_list_e2e_jobs_returns_proof_events and
  test_list_e2e_jobs_route_returns_200 — 92 tests pass (was 90)
- py_compile passes on both locked files
- provider 401 remains user-action only: I1 audit confirmed HTTP 401
  is a pure invalid API key issue; no provider HTTP code touched

Task: H3D-CLAUDE24-I2-E2E-CODE-LOOP
Hermes evidence chain: PASS

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(I3): OpenCode/OpenHands sandbox readiness + GET preflight route (#121)

* feat(I3): OpenCode/OpenHands sandbox readiness + GET preflight route

- Add opencode_openhands_sandbox_readiness() in code_history.py returning
  the I3-spec shape: opencode_detected, opencode_version, openhands_detected,
  openhands_image, sandbox_network_mode (always "none"), denied_paths, ready
- Add preflight_code_cli_runner_get() for non-mutating --version dry-run
  (GET variant, no task claim required); returns stdout, exit_code, elapsed_ms
- Wire GET /api/code-operator/sandbox/readiness to new function (replaces
  Docker-based response with OpenCode/OpenHands detection schema)
- Add GET /api/code-operator/cli-runners/preflight?runner_id=opencode|openhands
- Add SandboxReadiness panel to Agents.tsx with real detected/not-detected
  badges (data-testid=sandbox-readiness-panel), Refresh button, network mode
  and denied-paths display — no fake states
- Evidence: ev_040fad5fbd843c38 (opencode v1.4.3-hermes3d detected, exit_code=0)
- 38 unit tests green; task H3D-CLAUDE24-I3-OPENCODE-OPENHANDS released

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(I3): wire setSandboxBusy into Refresh onClick — resolve TS6133

Layer D2 UI-Final failed because setSandboxBusy was declared but its
setter was never invoked (TS6133). Wire it correctly: setSandboxBusy(true)
before the fetch, .finally(() => setSandboxBusy(false)) after, so the
Refresh button correctly shows "checking" during load and CI passes.

Evidence: ev_ffa9a8c3e3bd4a40 | Task: H3D-A1-PR121-FIX

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(I7): firmware source inventory probes — read-only git describe, source_reference_only contract (#120)

- Add FIRMWARE_SOURCE_PATHS registry mapping all 6 firmware module IDs to
  their actual source checkouts under Hermes3D-OS/source-lab/sources/
- Add _git_describe(): read-only subprocess.run(git describe --tags --always)
  with timeout=5s; returns None on any error — no flash/compile/serial
- Add probe_firmware_source_inventory(module_id): returns source_found,
  version_tag, runner_status=source_reference_only, agent_executable=False
- Add probe_all_firmware_sources(): aggregates all 6 modules in one call
- Update BUILTIN_RUNTIME_PROBES firmware entries: path fields now point to
  confirmed source checkouts; kind changed to firmware_source_inventory
- Add 04_testing/pytest/unit/test_firmware_farm_probes.py — 49 tests:
  registry coverage, contract template, _git_describe (mocked), per-module
  parametrized happy/absent paths, safety constraint enforcement tests
- Live probe result (evidence ev_842d77f8663ea2ee):
  firmware_klipper=293e1e9, marlin=03cc75f, prusa_firmware=f3e0dfd,
  reprapfirmware=f4297ad, repetier_firmware=7cb3741, smoothieware=620e162
- ABSOLUTE CONSTRAINTS: no avrdude/dfu-util/openocd/esptool, no serial port,
  no make/cmake/platformio, S1 not probed, T1/V400 source-only

Hermes evidence chain: PASS
Task ID: H3D-CLAUDE24-I7-FIRMWARE-FARM
Evidence ID: ev_842d77f8663ea2ee

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(I6): service/web-app health probes + service_web_health_runner status (#122)

Add seven named read-only HTTP probe functions (probe_fluidd, probe_mainsail,
probe_octoprint, probe_fdm_monster, probe_octofarm, probe_manyfold,
probe_comfyui) plus a probe_service_web_health dispatcher.  Each probe uses
GET with a 3-second timeout, never POSTs, never mutates, and is blocked with
reason=no_configured_url when the env var is absent.

Update _runner_status to return service_web_health_runner (replacing the
generic readonly_api_ready) for local_http_health verifier kind, and add
service_web_health_runner_contract to _required_verifier_family.

Add 74-test suite in test_module_runtime.py covering: dispatcher routing,
blocked-when-no-url, non-local-URL guard, HTTP 200 happy path (mocked),
connection-error handling, 4xx handling, runner-contract status assertions,
and GET-only method verification.  Update pre-existing test in
test_source_runtime_contracts.py to reflect the new runner_status value.

All 226 unit tests pass (74 new, 116 combined with existing module tests).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(I5): slicer/modeler CLI probes — PATH detection, --version proof, exact blocked reasons (#123)

* fix(I4): add runner_family to all 60 runner-contracts + blocked_reason for BLOCKED rows

- Add _contract_runner_family() mapping runner_status → valid family string
- Add runner_family field to module_runner_contract() return dict (was absent,
  causing all 60 /runner-contracts rows to have FIELD_MISSING)
- Fix blocked_reason for slic3r and superslicer (runner_status=blocked):
  previously suppressed by cli_install_config_available=True condition; now
  always set when runner_status==blocked regardless of preflight runner
- Valid families emitted: agent_cli_ready, read_only_runner, executable_path,
  python_import_repair, cli_install_config, npm_package_preflight,
  desktop_app_runner_gap, gpu_worker_runner_gap, runtime_repair_required,
  source_reference_only, blocked, metadata_ready_needs_runner
- 113 pytest tests pass; only locked file modified

Task: H3D-CLAUDE24-I4-SOURCEOS-CORE
Hermes evidence chain: PASS
Gates run: python -m py_compile (both files), pytest 113 passed
Rows fixed (null→known runner_family): 60

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(I5): slicer/modeler CLI probes — PATH detection, --version proof, exact blocked reasons

Adds probe_slicer_cli() and probe_modeler_import() to module_runtime.py.
Non-mutating: --version/help only, no STL sent, no firmware flashed.

Detected (on this machine):
  Slicers: PrusaSlicer 2.9.5, OrcaSlicer, FLSUN Slicer 2.0.4, CuraEngine 5.12.1, BambuStudio
  Modelers: Blender 5.1.1, OpenSCAD 2021.01, trimesh 4.12.1, pymeshlab

Blocked (exact path tried recorded):
  Slicers: SuperSlicer (not at C:/Program Files/SuperSlicer/), Slic3r (not installed)
  Modelers: FreeCAD (FreeCADCmd not at standard paths), cadquery/build123d/numpy-stl/open3d (not importable), truck (source-inventory only)

Adds SLICER_MODULE_IDS, MODELER_PYTHON_IMPORT_IDS, MODELER_SOURCE_INVENTORY_IDS constants.
Adds _find_slicer_executable() with canonical + alt + PATH search.
Handles PrusaSlicer/OrcaSlicer/BambuStudio/FLSUN nonzero --version exit codes.

Tests: 43 new slicer/modeler probe tests + 42 existing contract tests = 85 total, all green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(I10): reduce polling lag, fix sidebar overflow, layout fixes (#110)

- AppShell: remove lg:overflow-hidden on main in dashboard mode to prevent panel cutoff on large viewports (overflow-auto retained throughout)
- Sidebar: wrap AgentChatMirror in min-h-0 shrink container so tall chat panel no longer displaces nav items off-screen
- TopBar: fix stale data — was fetch-on-mount only; add 10 000 ms setInterval refresh for system snapshot, notifications, and proof bundle (non-critical display data)
- globals.css: no changes needed (font-size 13px and dashboard-grid overflow-hidden are intentional)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(I11): SourceOS 60-row rendering, real API wiring, panel overflow (#114)

- Fetch /api/modules/runtime/runner-contracts on mount + after Verify All / Setup Queue actions
- Map runner_status (runner_family) per module_id into a lookup dict
- ModuleList: display runner_family badge for each of the 60 rows using real runner_status from contracts endpoint
- AppDetailPanel: add runner_family header pill + RunnerContract InfoBox showing runner_status, required_verifier_family, safe_actions, acceptance_gate, and blocked_reason
- Pass runnerContract down to AppDetailPanel and refresh it in onRefresh callback
- All 60 rows rendered without slice/limit (confirmed via /api/modules count:60)
- Controls (Verify, Setup Plan, Backup, Rollback) already wired to real API — confirmed no fake handlers
- Panel overflow: AppDetailPanel section has overflow-auto in flex container with min-h-0

scan_active_ui_no_fake: 81 production files scanned, 0 findings

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(I13): print workflow — remove fake job states, policy-gate print actions (#113)

Dashboard: rename PIPELINE_STAGES to PIPELINE_STAGE_ICONS and remove the
hardcoded status:'complete'/'active' fields from the lookup table. Those
fields were dead code (PipelinePanel always derives status from live API
stage data); keeping them risked a developer treating them as truth.

Autopilot: remove EXPECTED_READINESS_CHECKS=16 magic constant. The gate
'allReady' was permanently blocked unless the backend returned exactly 16
checks — even if every returned check passed. Now allReady is true when
checks.length > 0 && all returned checks are ready (API is source of
truth). Added a "loading…" label and empty-state message while the API
response is pending so the UI never shows 0/0 as a misleading ready count.

Jobs: remove the 'counts' useMemo that injected 0 into every non-active
filter tab badge. Showing "Queued 0 | Done 0 | Failed 0" without fetching
those counts is a fake/misleading value. Now only the active filter shows
a live count; inactive filter tabs show no count badge.

Printers: no fake states found — all print actions await real API
confirmation before updating UI, and S1 policy block is correctly enforced.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(observe): real health probing in /cameras, remove fake events, fix initial feed state (#115)

- observe.py /api/observe/cameras: replaced static _configured_camera_state()
  (always "configured") with a real _probe_camera_timed() call per camera so
  health reflects actual connectivity, not just URL presence.
- Observe.tsx initialFeedState: cameras with health="unreachable" now start in
  "error" state instead of "loading", preventing endless "CONNECTING" badge on
  known-dead feeds.
- ObserveConsole.tsx: removed hardcoded fake EVENTS strings; events panel now
  derives per-camera status lines from the real /api/observe/status response.
  Polling interval documented (STATUS_POLL_INTERVAL_MS = 5000ms >= 3000ms).

Task: H3D-CLAUDE24-I9-OBSERVE-CAMERA
Hermes evidence chain: PASS

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(I12): agent chat blocked state, voice text+audio+mute, learning real states (#117)

- AgentChatMirror: extract real blocked reason from response body (HTTP 401
  from MiniMax/DeepSeek now shows the provider error text, not just status code)
- AgentChatMirror: add explicit 'Providers blocked' banner in chat history
  when agent roster is empty, with action text for G:\private\.env config
- Voice.tsx: add mute button to TTS preview (Voice Browser fine-tuning panel)
  and transcript playback — muting suppresses audio but ALWAYS shows text
- Voice.tsx: text transcript displayed in all states; muted state explicitly
  shown with amber indicator so user knows audio is off but text remains visible

Voice API probe: GET /api/voice/status → 404 (route not registered in backend);
GET /api/voice/providers → Azure Speech READY (configured, region=westus).
TTS routes through backend /api/voice/preview (confirmed base64 response).
Learning: real API calls only, blockers shown with real reasons (confirmed live).
No-fake scan: PASS (81 production files, no mock/fake/simulated UX markers).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(provider): align MiniMax and DeepSeek runtime adapters (#124)

* docs(handoff): tighten Hermes runtime finish contract

* docs(sweep): PR #125 control sweep handoff + runtime finish report

- HERMES_RUNTIME_FINISH_REPORT.md: 10-agent audit results, merge
  matrix, provider BLOCKED verdict (HTTP 401 both providers)
- PR125_CONTROL_SWEEP_HANDOFF_2026-05-09.md: full PR #125 sweep —
  A1-A10 audit results, zombie lock recovery, secret safety PASS,
  printer safety PASS, exact env key fixes required, next actions

Task: H3D-PR125-SWEEP-DOCS | Evidence: ev_dbf23c31c04af4ca, ev_a736131a4b0d8c6e

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(provider): align MiniMax and DeepSeek runtime adapters

- prefer MiniMax highspeed token-plan aliases and keep Max-Highspeed model routing explicit
- update MiniMax gateway to use MiniMax-M2.7-highspeed and max_completion_tokens
- update DeepSeek gateway/tests to use deepseek-v4-pro reasoning payload
- allow minimax/deepseek in llm policy and refresh provider rescue handoff docs
- keep provider smoke redacted; MiniMax now selects token-plan env and returns 429 insufficient_balance, DeepSeek remains 401

* docs(rescue): provider rescue blocker proof — adapters correct, blockers user-side

PR #124 provider completion sweep. Wave 1-3 audit:
- MiniMax adapter (gateways/providers/minimax.py): CORRECT per official docs.
  Reaches api.minimax.io. HTTP 429 insufficient_balance (1008) is
  provider-side billing/quota, NOT code, NOT auth.
- DeepSeek adapter (gateways/providers/deepseek.py): CORRECT per official
  docs. Posts to api.deepseek.com/chat/completions with thinking +
  reasoning_effort for v4-pro. HTTP 401 = "wrong API key" per
  api-docs.deepseek.com/quick_start/error_codes (single documented cause).

No code fix needed. Both blockers are out-of-repo user actions:
1. MiniMax: top up Token Plan balance / OAuth portal auth at platform.minimax.io
2. DeepSeek: rotate DEEPSEEK_API_KEY in G:/private/.env

Hermes Agent loop remains BLOCKED until both providers return accepted:true.

Evidence: ev_cffabca307652c21 (minimax), ev_bdec2f02c01c17ec (deepseek),
ev_491fe9d07426cab4 (adapter audit).
Task: H3D-CLAUDE-PROVIDER-COMPLETION.
No private values exposed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(code-operator): expose redacted CLI provider env contract

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(agent): tighten control gates (#125)

* docs(rescue): mark blocker proof SUPERSEDED — providers now PASS (#132)

First proof-gated Hermes Agent coding loop. The full chain ran end-to-end
including a real recovery cycle:

  MiniMax build (artifact 08c8dce66b3a4a589572cee225f2b428)
  -> DeepSeek review v1 BLOCKED_ON_INSUFFICIENT_EVIDENCE
  -> v1 proposal 8365f7833f10... DeepSeek APPROVE ev_675dcddbd474c55d
  -> apply -> git-diff-check FAIL on trailing whitespace from `  ` line breaks
  -> rollback to snapshot 6f478adcf452 (proof 245d7fd376fc)
  -> v2 proposal f07e6af14f5f authored without trailing whitespace
  -> DeepSeek APPROVE v2 ev_59947bb44bf1715a
  -> apply -> git-diff-check PASS gate_git-diff-check_1778295564288

Provider smoke evidence baked into the SUPERSEDED block text:
  minimax  ev_4a52d9b1336ca9f2  HTTP 200  MiniMax-M2.7-highspeed
  deepseek ev_e708071cb269f170  HTTP 200  deepseek-v4-pro

No private values exposed. Same-owner MCP locks throughout.

Task: H3D-FIRSTLOOP-001-SUPERSEDE

Hermes evidence: f07e6af14f5f4db3972fdc1bb336bd35, ev_59947bb44bf1715a, ev_675dcddbd474c55d, ev_4a52d9b1336ca9f2, ev_e708071cb269f170, ev_a2780d9832e5567a, ev_95e16427ce056505, ev_69e00f87178d6f9c

* feat(recovery): Hermes Agent Recovery Controller v1 (lean ledger) (#133)

First lean v1 of the Hermes Agent Recovery Controller, born from the
recovery cycles in PR #126. Backend ledger ONLY: no UI, no autonomous
apply, no file mutation by the controller. Future-proof v1.5 schema
fields included so the upcoming Hermes Agent Task Monitor UI can read
rich state without backend refactor.

What ships:
- code_history.py: RECOVERY_FAILURE_CLASSES (9), RECOVERY_OUTCOME_STATUSES
  (3), RECOVERY_FAILED_STEP_TYPES (10), RECOVERY_RECOMMENDED_ACTIONS (8),
  RECOVERY_REDACTION_STATUSES (3), RECOVERY_WORKER_OUTPUT_STATUSES (6),
  RECOVERY_AGENT_STACK_VALUES (8), _RECOVERY_LEDGER_PATH, plus
  record_step_failure(), mark_recovery_outcome(), list_recovery_attempts().
  Adds `import secrets` and `from hermes3d.gateways.redaction import
  redact_text` to imports.
- code_operator.py: RecoveryRecordFailureRequest, RecoveryMarkOutcomeRequest
  StrictBody models + 3 routes: POST /recovery/record-failure, POST
  /recovery/mark-outcome, GET /recovery/state.
- test_code_operator.py: 7 lean v1 tests covering record/reject/redact/
  mark/state via TestClient with unique uuid4 task_ids.
- docs/handoffs/REVIEW_PACKET_*.md: 4 proof artifacts (full diff +
  contract per file) used in DeepSeek per-file review.

Provenance chain (each step proof-anchored):
- MiniMax artifacts 2130e9e1d12d4686ac4d788bfd136673 (build pass 1) +
  459bc9c00d6049dd949fa84e61f09c7a (build pass 2). BOTH truncated by
  completion-token budget. Manual fixes preserved chain-of-custody:
    (a) merge_conflict -> merge_git_fail (test class typo)
    (b) test_state_route_returns_attempts re-authored from truncation
    (c) `import secrets` added (MiniMax used secrets.token_hex without
        adding the import)
    (d) v1.5 future-proof fields added per user spec
- Per-file DeepSeek review APPROVE:
    code_history.py    proposal b63cd8b665bf4c2488591f8350b91cf5
                       review   ev_5635d54ac7fdcec7
    code_operator.py   proposal 7b76f0eae91a4f0d8c80850fcef0b4f0
                       review   ev_d9225ed939f77eb2
    test_code_operator proposal 33d7dbc691b146f7a495c6c23fa148b0
                       review   ev_4d1ca4217e6b226c
- Recovery cycle (gate failure -> targeted fix):
    pytest NameError: redact_text -> follow-up proposal
    fe2371073c3d4267b5e0e049df13e5b7 -> DeepSeek APPROVE
    ev_5586c466df5d59aa -> applied evidence ev_647bfc4e38e0738f.

Gates after final apply:
- python -m py_compile (code_history.py + code_operator.py): exit 0
- python -m pytest test_code_operator.py: 50 passed
- scan_active_ui_no_fake.py: 81 files, 0 markers
- git diff --check: exit 0
- hermes_run_gate git-diff-check: PASS gate_git-diff-check_1778298845085

Provider smoke evidence still PASS: minimax ev_4a52d9b1336ca9f2,
deepseek ev_e708071cb269f170. No private values exposed.

Next slice (separate PRs): autonomous repair dispatch (v2), Hermes Agent
Task Monitor UI (v3). v0.13.0 upstream Hermes Agent update is its own
proof-gated lane.

Task: H3D-RECOVERY-CTL-V1

Hermes evidence: b63cd8b665bf4c2488591f8350b91cf5, 7b76f0eae91a4f0d8c80850fcef0b4f0, 33d7dbc691b146f7a495c6c23fa148b0, fe2371073c3d4267b5e0e049df13e5b7, ev_5635d54ac7fdcec7, ev_d9225ed939f77eb2, ev_4d1ca4217e6b226c, ev_5586c466df5d59aa, ev_788974be0aa90ccd, ev_cbdcc4bca447d895, ev_e1ba5ddf993149bb, ev_647bfc4e38e0738f, ev_4a52d9b1336ca9f2, ev_e708071cb269f170

* docs(gui): add Hermes3D OS visual reference pack (#134)

* fix(agent-updates): harden staged-update pytest gate (Audit PR #135 follow-up) (#136)

Mirrors upstream NousResearch/hermes-agent tests.yml flags so the staged
update gate cannot fake-pass while v0.13.0 is formally deferred. Closes
the CICD-SEC-1 / Codecov-2021-style fake-pass surface in
_run_update_checks.

Patch
- Path ignores: --ignore=tests/integration --ignore=tests/e2e match
  upstream tests.yml. Marker-only -m "not integration" cannot block
  tests/e2e/conftest.py from polluting sys.modules at collection time
  (sys.modules["discord"] = MagicMock leak proven during Cplus-py311
  Phase 4 bisection).
- Workers env: HERMES_AGENT_PYTEST_WORKERS (default "4", mirrors GHA
  4-vCPU runner). Production rejects <2 with HTTPException(400);
  HERMES_AGENT_DIAGNOSTIC=1 overrides for triage. "auto" sentinel
  accepted. Garbage strings raise 400.
- maxfail: 1 in production (matches upstream tests.yml), 5 in
  diagnostic mode for triage-friendly multi-failure output.
- Skip path now fail-closed: missing HERMES_AGENT_RUN_PYTEST surfaces
  as status="fail" with "REQUIRES_CONFIRMATION:" output, never
  status="skipped" or 200/OK. Removes the fake-pass path that let
  pytest=skipped roll up as gate=verified.
- Timeout 300s -> 600s. Larger collected set under upstream-aligned
  --ignore needs the longer budget.

Tests
- 04_testing/pytest/unit/test_agent_updates_meta.py (3 tests):
  upstream tests.yml still has both --ignore= flags (network test,
  skip-on-offline), local source mirrors them, diagnostic+workers
  guard names + default value present.
- 04_testing/pytest/unit/test_agent_updates_skip_path.py (11 tests):
  skip-path fail-closed when env unset/zero, workers 0/1 rejected in
  production, workers 0 allowed in diagnostic mode, garbage raises
  400, default workers="4", path-ignores in pytest args, diagnostic
  uses --maxfail=5, "auto" sentinel accepted.

Result: 14/14 pass on 04_testing/pytest/unit.

Scope
- v0.13.0 update remains formally deferred (Cplus-defer-formal).
- This PR fixes the gate only; no runtime update was installed.
- Sources: PR #135 / commit 5ecd8ff (Batch 2 Agent 6 + Agent 10).

Follow-ups (separate PRs)
- Bonus 12: recovery ledger file lock, mark_recovery_outcome
  idempotency, agent_updates.py:115 HTTPException auto-repair gap,
  apply_patch_proposal TOCTOU.
- Bonus 13: 60-app audit doc errata (loader-real registry path,
  42 SPDX-invalid licenses).
- Upstream Agent 11 tickets (firmware archive-dir validator deferred
  here; YAML schema lacks the field today).

References
- https://raw.githubusercontent.com/NousResearch/hermes-agent/main/.github/workflows/tests.yml
- https://docs.pytest.org/en/stable/example/pythoncollection.html#ignore-paths-during-test-collection
- https://owasp.org/www-project-top-10-ci-cd-security-risks/
- https://about.codecov.io/apr-2021-post-mortem/

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(recovery): close Bonus 12 ledger races + auto-repair escape (PR #135) (#137)

Three findings from the Bonus 12 audit (PR #135 / bonus12-bug-finder.md):

Finding #1 (blocker, services/code_history.py recovery ledger)
- Append-without-lock allowed concurrent record_step_failure /
  mark_recovery_outcome calls to interleave partial JSONL lines on
  Windows. mark_recovery_outcome would silently json.JSONDecodeError-
  skip the corrupted entries and report "attempt_id not found".
- Fix: new _RecoveryLedgerLock context manager that combines a
  process-local threading.Lock with an OS-level advisory lock on a
  sidecar lockfile. Uses fcntl.flock on POSIX and msvcrt.locking on
  Windows; both stdlib, no new deps. flush()+os.fsync() on every
  append.

Finding #2 (major, mark_recovery_outcome)
- No idempotency check: a retry could append a SECOND outcome row,
  producing ambiguous state for list_recovery_attempts consumers.
- Fix: read scan now happens inside the same lock as the append.
  If any outcome row for attempt_id already exists, raise
  ValueError("already has a recorded outcome") atomically.

Finding #3 (major, agent_updates.py:115)
- _run_git raises HTTPException(502) on non-zero exit. A failed
  mid-step "git checkout --detach <tag>" escaped the for-tag loop
  without reaching _auto_repair_to_backup, leaving the Hermes Agent
  checkout on the previous (still-unverified) tag and surfacing 502
  to the caller instead of structured rollback.
- Fix: wrap the per-tag checkout + _run_update_checks in
  try/except HTTPException; record a synthetic step failure with the
  redacted detail and pivot to _auto_repair_to_backup. Also catches
  the HERMES_AGENT_PYTEST_WORKERS validation 400 added in PR #136.

Tests added (11 total, all green)
- 04_testing/pytest/unit/test_recovery_ledger_locking.py (8 tests)
  * lock helper exposes a backend (fcntl/msvcrt/thread-only)
  * 12-thread x 25-write concurrency test: every line round-trips
    through json.loads (no torn writes)
  * record_step_failure writes complete JSONL line + creates parent
    directory + lockfile sidecar
  * mark_recovery_outcome first call succeeds; second call raises
    ValueError with "already has a recorded outcome"
  * unknown attempt_id still raises "not found in recovery ledger"
  * race test: two threads finalize same attempt_id; exactly one
    succeeds, one raises idempotency error
- 04_testing/pytest/unit/test_agent_updates_auto_repair.py (3 tests)
  * failed checkout pivots to _auto_repair_to_backup (no 502 escape)
  * failed _run_update_checks (workers env 400) also pivots
  * all-pass path unchanged (smoke regression guard)

Verification
- py_compile: OK on all 4 files
- Focused tests: 25/25 pass (11 new + 14 from PR #136)
- Pre-existing failures in test_source_runtime_contracts.py (5
  firmware tests blocked instead of ready) confirmed pre-existing
  on base; out of scope for this PR.

Scope
- Recovery Controller v2 (RC v2) commits 2-5 stay paused per user
  instruction; RC v2 depends on the recovery correctness this PR
  restores.
- Hermes Agent v0.13.0 update remains formally deferred.
- Bonus 13 audit doc errata is out of scope (separate PR).

References
- https://docs.python.org/3/library/fcntl.html#fcntl.flock
- https://docs.python.org/3/library/msvcrt.html#msvcrt.locking
- https://about.codecov.io/apr-2021-post-mortem/
- https://owasp.org/www-project-top-10-ci-cd-security-risks/

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(agent-updates): harden _zip_dirty_entries (Bonus 12 #4 / PR #135) (#138)

Defense-in-depth on the dirty-files backup zip in
api/routes/agent_updates.py:_zip_dirty_entries.

Pre-fix issues
- Opened the zip without allowZip64=True, so >4 GiB dirty backups
  silently truncate on Python builds that default to no-zip64.
- Used path.relative_to(repo) against an un-resolved repo path,
  raising ValueError and aborting the whole backup whenever the repo
  path is itself a symlink.
- A symlink in the dirty tree could resolve to a target outside the
  repo and still produce an arcname inside the archive, surfacing
  CWE-22 path traversal on extract.

Post-fix
- allowZip64=True passed to ZipFile.
- path.is_symlink() check skips symlinks defensively (even though
  _dirty_entries usually pre-resolves; tests / future callers may not).
- Arcname computed against repo.resolve() so symlinked checkouts
  (e.g. /tmp/repo -> /var/checkout) work cleanly.
- Arcname asserted to be a pure relative path (no absolute,
  drive-letter, parent-traversal, or empty components).
- Resolved-target paths that fall outside the repo are silently
  dropped instead of leaking into the archive.

Tests added (8, all green)
- 04_testing/pytest/unit/test_agent_updates_zip_dirty.py
  * normal files round-trip with relative arcnames
  * empty paths list short-circuits without creating an archive
  * symlinks (in-repo target) skipped — CWE-22 guard
  * symlinks (out-of-repo target) skipped — exfiltration guard
  * symlinked repo root produces correct arcname (no ValueError)
  * out-of-repo path silently dropped
  * allowZip64=True passed (probe via ZipFile subclass)
  * pathological absolute Path components silently dropped

Verification
- py_compile: OK
- 25/25 agent_updates-keyed unit tests pass
- Secret-leak scan on touched files: only descriptive test fixture
  string "outside-secret" (not a real secret)
- Pre-push hook: passed

Scope
- Bonus 12 finding #4 only (continuing the controlled-batch pattern
  from PR #137).
- v0.13.0 update remains formally deferred.
- RC v2 commits 2-5 remain paused per user instruction.

References
- https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile
- https://cwe.mitre.org/data/definitions/22.html

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(audit): 60-App Update Readiness Audit (docs-only, no runtime change) (#135)

* docs(audit): 60-App Update Readiness Audit + Phase 4 v2 patch proposal

Audit/planning lane only. No app updates. No GUI changes. No source mutation
beyond this doc. Hermes Agent v0.13.0 stays formally deferred per the
2026-05-09 user decision in handoffs/HERMES_AGENT_V013_UPDATE_LANE_CPLUS_PY311_DOCKER_FORMAL_DEFER.

What's in the audit:
- Per-app profile matrix: 60 rows across 11 sections (slicers 11 / modelers 13
  / 3D-gen 6 / print-farm 10 / firmware 6 / agent-cli 7 / library 1 / materials
  1 / hardware 3 / utilities 1 / research 1). Each row: update method, proof
  command, runtime env, deps, rollback method, blockers, recommended lane,
  auto-upd…
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