Skip to content

chore(submodule): promote PMOVES-hermes-agent to hardened tip (42 upstream commits) - #2511

Merged
POWERFULMOVES merged 2 commits into
mainfrom
chore/promote-hermes-agent-gitlink-2026-08-10
Aug 12, 2026
Merged

POWERFULMOVES merged 2 commits into
mainfrom
chore/promote-hermes-agent-gitlink-2026-08-10

Conversation

@POWERFULMOVES

@POWERFULMOVES POWERFULMOVES commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Summary

Promotes the PMOVES-hermes-agent gitlink from 863e313140765f769c on PMOVES.AI-Edition-Hardened.

Pure upstream sync — 42 commits advance on the hardened branch. Zero PMOVES-authored commits in the delta. Upstream = NousResearch/hermes-agent@main, merged via fork-sync PR #3 (admin-merged; the only failing check was upstream contributor attribution which does not apply to a pure upstream sync).

Why

Unblocks:

  • Mavis join on SPARK (was waiting on the Hermes fork to be current)
  • Evolution Fabric Wave 0 three-body review (Crush + Hermes + Archon) per pmoves/docs/handoffs/SPARK_EVOLUTION_FABRIC_HANDOFF_2026-08-04.md
  • All Hermes-dependent SPARK lanes (Jetson combiner fleet, Crush-in-Pinokio, HERMES_AGENT_INTEGRATION.md v0.18.2 profile)

Verification

Testing

  • git diff --cached shows exactly 1 line change (subproject commit SHA)
  • No parent-repo code touched; submodule-integrity gate will verify the gitlink is reachable

Summary by CodeRabbit

  • Chores
    • Updated the Hermes Agent component to a newer revision.
    • No user-facing functionality or behavior changes.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PMOVES-hermes-agent submodule reference changes from commit 863e31318553cda8ad61df681d08175364d4164b to commit 40765f769c2de35e64cca1b14ba4e93370098dad.

Changes

Hermes agent update

Layer / File(s) Summary
Hermes agent submodule pointer
PMOVES-hermes-agent
The submodule reference points to the new commit.

Estimated code review effort: 1 (Trivial) | ~2 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the submodule promotion and the hardened target, which matches the primary change.
Description check ✅ Passed The description provides a detailed summary, rationale, verification evidence, and testing notes for the gitlink-only update.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/promote-hermes-agent-gitlink-2026-08-10

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added chit-aware Touches a CHIT-aware service — control-body signature gate applies compose Compose files / service Dockerfiles docs Documentation services Service source under pmoves/services/ config pmoves/config(s)/ changes labels Aug 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔏 CHIT-aware change — control-body routing

This PR touches a CHIT-aware service (ports 8086/8087/8103/8106/8113/9224 surface). Before a Control-Body ACK:

  • the diff (or PR body) should reference a CHIT signature trail — chit.signed.v1, a CHIT: trailer, or a make -C pmoves sign-trail entry;
  • the chit-pr-audit-agent (.claude/agents/chit-pr-audit-agent.md) is the gate that grants/refuses ACK eligibility;
  • signing quickstart: pmoves/docs/AGENTS/CHIT_SIGNING_TUTORIAL.md.

Advisory routing only — the blocking contract check is CHIT Contract.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 50334650af

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pmoves/services/hf-research-agent/main.py
Comment thread pmoves/tools/beats_to_voice.py
Comment thread pmoves/tools/beats_to_voice.py
Comment thread .gitmodules

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 50334650af

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pmoves/services/hf-research-agent/main.py
Comment thread pmoves/tools/beats_to_voice.py
Comment thread pmoves/tools/beats_to_voice.py
Comment thread .gitmodules

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 18

Note

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

🟡 Minor comments (9)
pmoves/config/profiles/dgx-spark-grace-blackwell.yaml-22-31 (1)

22-31: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Synchronize the sidecar architecture documentation.

pmoves/docker-compose.spark-sidecar.yml still documents SM_110 in its DGX Spark header. This profile now declares SM_121. Update the sidecar header in this PR so operators do not use the obsolete architecture target.

As per coding guidelines, “update documentation or schemas when interfaces change.”

🤖 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 `@pmoves/config/profiles/dgx-spark-grace-blackwell.yaml` around lines 22 - 31,
Update the DGX Spark header in the sidecar configuration to replace the obsolete
SM_110 architecture target with SM_121, matching the compute_capability and tags
declared in the profile.

Source: Coding guidelines

pmoves/services/hf-research-agent/main.py-168-168 (1)

168-168: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Update the maximum-score test contract.

Line 168 now reports 110. pmoves/tests/services/test_hf_services.py, Line 187 still expects 100. The existing test will fail.

Proposed test update
-        assert result["max_score"] == 100
+        assert result["max_score"] == 110
🤖 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 `@pmoves/services/hf-research-agent/main.py` at line 168, Update the
maximum-score expectation in the relevant test case of test_hf_services.py to
match the 110 returned by the max_score calculation in the HF research agent,
preserving the existing assertion structure.
.gitignore-360-360 (1)

360-360: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Scope the 20.md ignore rule.

Line [360] ignores every file named 20.md at any directory depth. This can silently exclude unrelated documentation. If this is a root-level generated artifact, anchor the rule.

Proposed fix
-20.md
+/20.md
🤖 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 @.gitignore at line 360, Scope the 20.md ignore rule to the repository root
by anchoring the pattern, so nested documentation files named 20.md remain
trackable.
pmoves/services/flute-gateway/providers/ultimate_tts.py-365-377 (1)

365-377: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Validate the complete custom emotion vector before enabling vector_control.

Line 374 accepts values outside the documented [0,1] range. It also accepts nan and infinity. Lines 375-376 skip invalid components, but Line 377 still enables vector_control. This sends a partial vector with schema defaults in the skipped positions.

Parse all eight components first. Reject the vector unless every component is finite and within [0.0, 1.0]. Enable indextts2_emotion_mode only after validation succeeds.

🤖 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 `@pmoves/services/flute-gateway/providers/ultimate_tts.py` around lines 365 -
377, Update the indextts2 voice handling around emotion_names and set_by_name to
parse all eight vector components before applying any values. Reject the vector
if any component is non-numeric, non-finite, or outside [0.0, 1.0], and only
then set the components and enable indextts2_emotion_mode to vector_control; do
not leave partial values applied for invalid vectors.
pmoves/docs/handoffs/DARKXSIDE_E2B_DESKTOP_FANOUT_2026-08-06.md-13-13 (1)

13-13: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add language identifiers to the fenced blocks.

Use text for the architecture tree and shell for the local-stack commands. This resolves MD040.

Also applies to: 40-40

🤖 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 `@pmoves/docs/handoffs/DARKXSIDE_E2B_DESKTOP_FANOUT_2026-08-06.md` at line 13,
Update the fenced code blocks in DARKXSIDE_E2B_DESKTOP_FANOUT_2026-08-06.md by
adding the text language identifier to the architecture tree block and shell to
the local-stack command block, including the additionally referenced block, so
all fences satisfy MD040.

Source: Linters/SAST tools

pmoves/docs/handoffs/DARKXSIDE_E2B_DESKTOP_FANOUT_2026-08-06.md-55-76 (1)

55-76: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Mark the closing safety statement as target state.

The document says integration and secrets are not wired, and Phases 1–3 are future actions. The final sentence says the capability is already active. Rewrite it as a target state or link completed smoke and runbook evidence.

Also applies to: 174-174

🤖 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 `@pmoves/docs/handoffs/DARKXSIDE_E2B_DESKTOP_FANOUT_2026-08-06.md` around lines
55 - 76, Update the closing safety statement in the handoff document to describe
the E2B capability as a target state, consistent with the unwired integrations
and future Phases 1–3. Alternatively, retain an active-state claim only if it
links concrete completed smoke-test and runbook evidence.

Source: Path instructions

pmoves/docs/handoffs/DARKXSIDE_HAVEN_RETICULUM_FANOUT_2026-08-06.md-12-22 (1)

12-22: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add language tags to both diagram fences.

Line 12 and Line 52 start fenced blocks without a language. Add text to satisfy markdownlint MD040.

Proposed markdown fix
-```
+```text

Also applies to: 52-81

🤖 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 `@pmoves/docs/handoffs/DARKXSIDE_HAVEN_RETICULUM_FANOUT_2026-08-06.md` around
lines 12 - 22, Add the text language tag to both fenced code blocks in the
document, including the diagram beginning with “PMOVES.AI Agents” and the second
block around the referenced later section, so each opening fence is ```text and
satisfies markdownlint MD040.

Source: Linters/SAST tools

pmoves/docs/handoffs/DARKXSIDE_HAVEN_RETICULUM_FANOUT_2026-08-06.md-204-209 (1)

204-209: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Model /dev/ttyUSB0 as a device in Compose.

If this service supports local RNode LoRa, describe /dev/ttyUSB0 as a device mapping, not a volume. Use devices: - "/dev/ttyUSB0:/dev/ttyUSB0" or a stable /dev/serial/by-id/... mapping in the Compose service.

🤖 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 `@pmoves/docs/handoffs/DARKXSIDE_HAVEN_RETICULUM_FANOUT_2026-08-06.md` around
lines 204 - 209, Update the reticulum-bridge service definition in
docker-compose.yml so the local RNode path is declared under devices rather than
volumes. Map /dev/ttyUSB0 to the same container path, or use a stable
/dev/serial/by-id mapping, while preserving the existing service configuration.
pmoves/docs/handoffs/DARKXSIDE_HAVEN_RETICULUM_FANOUT_2026-08-06.md-94-97 (1)

94-97: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Use one exact LoRa profile across both lists.

SF7-9 and the missing txpower make the RNode provisioning inconsistent with the RNS block. Select one exact spreading factor and transmit power, then use the same values in the flashing instructions and the [[LoRa RNode]] config.

🤖 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 `@pmoves/docs/handoffs/DARKXSIDE_HAVEN_RETICULUM_FANOUT_2026-08-06.md` around
lines 94 - 97, Update the RNode flashing instructions and the [[LoRa RNode]]
configuration to use one identical LoRa profile: replace the SF7-9 range with a
single spreading factor and add an explicit txpower value matching the RNS
block. Ensure frequency, bandwidth, spreading factor, coding rate, and transmit
power are consistent in both sections.

Source: MCP tools

🤖 Prompt for all review comments with 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.

Inline comments:
In @.gitmodules:
- Around line 384-398: Add the missing PMOVES-ollama gitlink entry to the parent
index with mode 160000 and ensure it matches the existing PMOVES-ollama
registration in .gitmodules; alternatively remove that registration if the
submodule is not intended to be tracked.

In `@PMOVES-fluidd`:
- Line 1: Update the PMOVES-fluidd gitlink to a commit reachable from its
configured submodule remote, using the exact valid upstream commit and
documenting the branch justification as required; otherwise revert the
PMOVES-fluidd submodule update to the previous reachable revision.

In `@pmoves/config/profiles/dgx-spark-grace-blackwell.yaml`:
- Around line 105-115: Update the torch_requirements pip_install entry to pin
both torch and torchaudio to the verified 2.11.0+cu130 versions, while
preserving the existing cu130 index URL and surrounding profile configuration.

In `@pmoves/docker-compose.yml`:
- Around line 3589-3590: Synchronize HF_PREFERRED_TAGS and HF_AVOID_TAGS
defaults between the Compose entrypoints by updating the corresponding
environment entries in docker-compose.agents.yml to use the same fallback values
as this block, or reuse a shared environment source. Preserve explicitly
supplied host values while ensuring unset variables no longer become empty
strings for the research agent.

In `@pmoves/docs/handoffs/DARKXSIDE_E2B_DESKTOP_FANOUT_2026-08-06.md`:
- Around line 166-170: Complete the Three-Body section by adding the required
claim row, release row, and signed ACK block, then link the Phase 3 command
evidence. Keep the existing Delivery, Control, and Memory entries intact and do
not treat the handoff as a release artifact until all evidence records are
present.
- Around line 86-91: Update the “Set self-hosted endpoints” instructions to keep
generated E2B secrets out of env.tier-worker and use env.shared or local.env
instead. Direct operators to run make -C pmoves secrets-funnel, configure
E2B_API_KEY_FILE and E2B_ACCESS_TOKEN_FILE, and load those secrets through
get_secret while preserving the endpoint and domain settings.
- Around line 94-100: Update the E2B MCP server specification near the listed
tools to define authentication, authorization, and ingress restrictions for port
8210. Require an explicit authenticated identity and least-privilege policy for
sandbox.create, sandbox.execute, and desktop-control tools, restrict ingress to
approved internal callers, and state that pmoves_app and pmoves_api network
membership is not an authorization mechanism.
- Around line 122-129: Update the Phase 3 validation sequence around
sandbox.execute to trigger every event in the expected five-subject set: add a
desktop click/type action and a spell invocation, then retain verification for
all subjects. Alternatively, remove subjects that are not exercised from the
expected event set.
- Around line 108-120: Define versioned JSON schemas for each new NATS subject
listed in section 3, and validate every published payload through
services/common/events.py. Register all subjects in
.claude/context/nats-subjects.md, document E2B ports and health endpoints in
.claude/context/services-catalog.md, and keep the five agent entries in
pmoves/config/agent_registry.yaml; include the E2B MCP and Desktop SDK in
.claude/CATALOG.md.

In `@pmoves/docs/handoffs/DARKXSIDE_HAVEN_RETICULUM_FANOUT_2026-08-06.md`:
- Around line 183-209: Complete the Phase 3 contract by defining versioned
*.v1.schema.json payload schemas for each Reticulum/Haven subject, documenting
producer/consumer ownership plus replay and idempotency behavior, and wiring
validation through services/common/events.py. Update the canonical context files
.claude/context/services-catalog.md with port 8220 and /healthz and /metrics,
.claude/context/nats-subjects.md with the new subjects, and
pmoves/config/agent_registry.yaml with the listed agents.
- Around line 276-280: Complete the Three-Body section by adding the required
claim row, work row, release row, and signed ACK block, linking each validation
result to its corresponding record. Ensure the handoff is not marked
production-ready until the full claim → work → sign → release evidence chain is
present.
- Around line 123-128: Update the [interfaces] [[Haven Mesh]] configuration
documentation for AutoInterface to include platform-specific firewall rules
permitting UDP ports 29716 and 42671 on both wlan0 and br-ahwlan. Add an offline
discovery smoke procedure covering reachability among wlan0, br-ahwlan, and
AirHop peers, including the expected successful result.
- Around line 163-179: Update the Fleet Bridge TCPServerInterface configuration
so it is reachable only through KVM4-2’s Tailscale address or an equivalent
host-firewall/device restriction; remove the unrestricted listen_ip value of
0.0.0.0 while preserving tailnet access for PMOVES nodes.
- Around line 226-229: Replace the unverified qwen3:30b statement in the Jetson
deployment flow with a testable model contract specifying the Orin Nano memory
SKU, exact quantized Ollama model tag, context length, and runtime. Add
cold-start and sustained-inference smoke-test requirements, and define a smaller
fallback model/tag selected when the 30B model cannot fit within container
memory.
- Around line 87-97: Update the Haven and RNode flashing instructions to record
immutable commit or release identifiers for the OpenWRT/MorseMicro image and
RNode binary, and require checksum or signature verification before flashing.
Also replace the Jetson-side unpinned pip3 install rns command with an
explicitly pinned RNS version.
- Around line 211-215: Update the “CHIT + Geometry Bus alignment” section to
account for the complete Reticulum/LoRa wire packet rather than only the raw CGP
state vector: include bridge metadata, signing/encryption overhead, and the
selected RNode configuration in the size budget. Define a maximum-size smoke
test and specify whether oversized packets are fragmented or rejected.

In `@pmoves/tools/beats_to_voice.py`:
- Around line 271-273: Replace the predictable timestamp-based path in the
synthesis output flow with a securely generated unique temporary file using
tempfile.NamedTemporaryFile(delete=False, suffix=".wav") or tempfile.mkstemp().
Write audio_bytes to that file and return the generated path, preserving the
existing WAV output behavior.
- Around line 249-255: Update synthesize_prosodic_speech() and its payload
construction so the prebuilt prosodic_chunks are included using the request
field or encoding required by Flute-Gateway’s /v1/voice/synthesize/prosodic
contract. Ensure the synthesis request sends the parsed boundary, pause,
duration, pitch, and position data instead of reconstructing only from
request.text, and keep the client aligned with the server’s supported request
schema.

---

Minor comments:
In @.gitignore:
- Line 360: Scope the 20.md ignore rule to the repository root by anchoring the
pattern, so nested documentation files named 20.md remain trackable.

In `@pmoves/config/profiles/dgx-spark-grace-blackwell.yaml`:
- Around line 22-31: Update the DGX Spark header in the sidecar configuration to
replace the obsolete SM_110 architecture target with SM_121, matching the
compute_capability and tags declared in the profile.

In `@pmoves/docs/handoffs/DARKXSIDE_E2B_DESKTOP_FANOUT_2026-08-06.md`:
- Line 13: Update the fenced code blocks in
DARKXSIDE_E2B_DESKTOP_FANOUT_2026-08-06.md by adding the text language
identifier to the architecture tree block and shell to the local-stack command
block, including the additionally referenced block, so all fences satisfy MD040.
- Around line 55-76: Update the closing safety statement in the handoff document
to describe the E2B capability as a target state, consistent with the unwired
integrations and future Phases 1–3. Alternatively, retain an active-state claim
only if it links concrete completed smoke-test and runbook evidence.

In `@pmoves/docs/handoffs/DARKXSIDE_HAVEN_RETICULUM_FANOUT_2026-08-06.md`:
- Around line 12-22: Add the text language tag to both fenced code blocks in the
document, including the diagram beginning with “PMOVES.AI Agents” and the second
block around the referenced later section, so each opening fence is ```text and
satisfies markdownlint MD040.
- Around line 204-209: Update the reticulum-bridge service definition in
docker-compose.yml so the local RNode path is declared under devices rather than
volumes. Map /dev/ttyUSB0 to the same container path, or use a stable
/dev/serial/by-id mapping, while preserving the existing service configuration.
- Around line 94-97: Update the RNode flashing instructions and the [[LoRa
RNode]] configuration to use one identical LoRa profile: replace the SF7-9 range
with a single spreading factor and add an explicit txpower value matching the
RNS block. Ensure frequency, bandwidth, spreading factor, coding rate, and
transmit power are consistent in both sections.

In `@pmoves/services/flute-gateway/providers/ultimate_tts.py`:
- Around line 365-377: Update the indextts2 voice handling around emotion_names
and set_by_name to parse all eight vector components before applying any values.
Reject the vector if any component is non-numeric, non-finite, or outside [0.0,
1.0], and only then set the components and enable indextts2_emotion_mode to
vector_control; do not leave partial values applied for invalid vectors.

In `@pmoves/services/hf-research-agent/main.py`:
- Line 168: Update the maximum-score expectation in the relevant test case of
test_hf_services.py to match the 110 returned by the max_score calculation in
the HF research agent, preserving the existing assertion structure.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 784d2317-dd08-46a2-a455-850bf2836fe8

📥 Commits

Reviewing files that changed from the base of the PR and between fba37ff and 5033465.

📒 Files selected for processing (15)
  • .gitignore
  • .gitmodules
  • PMOVES-OctoPrint-Obico
  • PMOVES-OrcaSlicer
  • PMOVES-fluidd
  • PMOVES-hermes-agent
  • PMOVES-moonraker-obico
  • PMOVES-obico-server
  • pmoves/config/profiles/dgx-spark-grace-blackwell.yaml
  • pmoves/docker-compose.yml
  • pmoves/docs/handoffs/DARKXSIDE_E2B_DESKTOP_FANOUT_2026-08-06.md
  • pmoves/docs/handoffs/DARKXSIDE_HAVEN_RETICULUM_FANOUT_2026-08-06.md
  • pmoves/services/flute-gateway/providers/ultimate_tts.py
  • pmoves/services/hf-research-agent/main.py
  • pmoves/tools/beats_to_voice.py

Comment thread .gitmodules
Comment thread PMOVES-fluidd
Comment thread pmoves/config/profiles/dgx-spark-grace-blackwell.yaml
Comment thread pmoves/docker-compose.yml
Comment thread pmoves/docs/handoffs/DARKXSIDE_E2B_DESKTOP_FANOUT_2026-08-06.md
Comment thread pmoves/docs/handoffs/DARKXSIDE_HAVEN_RETICULUM_FANOUT_2026-08-06.md
Comment thread pmoves/docs/handoffs/DARKXSIDE_HAVEN_RETICULUM_FANOUT_2026-08-06.md
Comment thread pmoves/docs/handoffs/DARKXSIDE_HAVEN_RETICULUM_FANOUT_2026-08-06.md
Comment thread pmoves/tools/beats_to_voice.py
Comment thread pmoves/tools/beats_to_voice.py
…tream commits)

863e3131 -> 40765f769c on PMOVES.AI-Edition-Hardened.

Pure upstream sync — NousResearch/hermes-agent main merged via fork-sync
PR #3 (admin-merged; the only failing check was upstream contributor
attribution which does not apply to a pure sync). Zero PMOVES-authored
commits in the delta. 42 commits advance on the hardened branch.

Unblocks Mavis join on SPARK + the Evolution Fabric Wave 0 three-body
review (Crush + Hermes + Archon) per SPARK_EVOLUTION_FABRIC_HANDOFF_2026-08-04.md.
@POWERFULMOVES

Copy link
Copy Markdown
Owner Author

Rebased onto main — was CONFLICTING/DIRTY, now clean and reduced to its actual delta.

PMOVES-hermes-agent | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

Conflict was .gitmodules — main added PMOVES-pinokio in the same region this branch adds its entries. Resolved keeping both; verified afterwards that PMOVES-pinokio survives, all five maker submodules are present, and there are no duplicate [submodule] stanzas.

Two commits dropped by the rebase as already-upstream — the DARKXSIDE fan-out briefs + fleet cleanup scripts, and the 5 maker/3D-printing submodules. Both are on main already, so the branch correctly reduces to the one thing its title claims: the hermes-agent gitlink promotion.

One note for anyone auditing this rebase, because it nearly produced a false report. Checking whether the maker submodules were on main with:

git show origin/main:.gitmodules | grep 'path = PMOVES-fluidd'

returned nothing on Windows — Git Bash rewrites origin/main:.gitmodules into origin\main;.gitmodules, git errors to stderr, and the pipe just sees an empty stream. It reads exactly like "the submodules were lost." With MSYS_NO_PATHCONV=1 the same command returns 402 lines and all five are present. A silent false negative in a verification command is worse than a loud failure — worth knowing before anyone concludes a rebase dropped work.

The 26 open review threads are untouched by this and still need a pass.

agent_signature (advisory, unsigned-local): ACK::CLAUDE-OPUS-5::PR2511-REBASE-2026-08-10

@POWERFULMOVES
POWERFULMOVES force-pushed the chore/promote-hermes-agent-gitlink-2026-08-10 branch from 5033465 to 148b68b Compare August 10, 2026 15:00
@github-actions github-actions Bot removed chit-aware Touches a CHIT-aware service — control-body signature gate applies compose Compose files / service Dockerfiles docs Documentation services Service source under pmoves/services/ config pmoves/config(s)/ changes labels Aug 10, 2026
…ned tip

The promoted gitlink was 40765f769c462f7dd91c7b3a7bc7b1be4ee5e4f7, which does
not exist in POWERFULMOVES/PMOVES-hermes-agent. Only the abbreviated SHA
40765f769c was ever handled; the remaining 30 hex chars were fabricated, so
the parent index pointed at an unreachable object and any
clone --recurse-submodules would have failed.

Real PMOVES.AI-Edition-Hardened tip is 40765f769c2de35e64cca1b14ba4e93370098dad
(same 10-char prefix). Verified against the remote:
  git ls-remote -> refs/heads/PMOVES.AI-Edition-Hardened = 40765f769c2de35e...
  compare 863e3131...40765f769c2de3 -> status=ahead, behind_by=0, 42 commits

Delta is 42 upstream commits, not the 49 claimed in the PR title.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@POWERFULMOVES

Copy link
Copy Markdown
Owner Author

Hedge-trim disposition — all 26 review threads

This PR was rebased onto main and is now a single 1-line delta: the PMOVES-hermes-agent gitlink. Two commits were correctly dropped as already-upstream (DARKXSIDE fan-out briefs, maker/3D-printing submodules). Every one of the 26 open threads was written against content that is no longer in this PR's diff — all 26 report isOutdated: true, and I verified each against gh pr diff 2511.

0 of 26 were live against the current diff. Resolving all 26 as outdated-by-rebase.

But the review did find a real bug — in the one line that is still here

The promoted gitlink was 40765f769c462f7dd91c7b3a7bc7b1be4ee5e4f7, which does not exist in POWERFULMOVES/PMOVES-hermes-agent:

gh api repos/POWERFULMOVES/PMOVES-hermes-agent/commits/40765f769c462f... -> 422 No commit found for SHA
git ls-remote ... | grep 40765f769c462f...                              -> 0 matches

Only the abbreviated SHA 40765f769c was ever handled (it is what the commit message and PR body both quote); the remaining 30 hex chars were fabricated. The parent index pointed at an unreachable object, so clone --recurse-submodules would have failed and the submodule-integrity gate would have flagged it.

Real PMOVES.AI-Edition-Hardened tip — same 10-char prefix, which is why this slipped through:

refs/heads/PMOVES.AI-Edition-Hardened = 40765f769c2de35e64cca1b14ba4e93370098dad
compare 863e3131...40765f769c2de3 -> status=ahead, behind_by=0, total_commits=42

Fixed in d5a692a. Gitlink now verifies: commit exists, is on the tracked branch, and 863e3131 is a strict ancestor (behind_by: 0).

Also corrected: the delta is 42 upstream commits, not the 49 in the original title (the commit body and PR description already said 42).

Upstream risk scan (42 commits, 110 files)

  • No dependency manifests touched (package.json, lockfiles, requirements*.txt, pyproject.toml, go.mod, Cargo.*) — no new CVE surface.
  • No BREAKING / CVE- / GHSA- markers in any commit message.
  • Two structural changes, both inert for this repo (git grep finds zero references in PMOVES.AI): skills/research/polymarket -> optional-skills/finance/polymarket, and removal of apps/desktop/src/plugins/gateway-pill/plugin.tsx.
  • Delta is pure upstream sync; largest changes are tests and cron/delegation lifecycle fixes.

Follow-ups for main (verified present there, out of scope for a gitlink bump)

These threads are outdated here, but I verified the underlying findings are real and currently on main. They belong in separate PRs:

  1. pmoves/services/hf-research-agent/main.py:168 returns "max_score": max_score + 10 (= 110) while pmoves/tests/services/test_hf_services.py:187 asserts result["max_score"] == 100. Deterministic failure whenever the HF suite's imports resolve (currently masked by the skipif import guard). This was Codex's P1 and it is correct.
  2. .gitmodules registers PMOVES-ollama (path/url/branch/ignore = all) but main has no 160000 gitlink at that path — 65 registered paths vs 64 gitlinks, PMOVES-ollama is the only orphan. CodeRabbit's finding is correct.
  3. .gitmodules — 5 submodules still have no branch field, so they are skipped by submodule-branch-policy-check / validate_submodule_gitlinks.sh and invisible to gitlink-promoter.yml: PMOVES-obico-server, PMOVES-moonraker-obico, PMOVES-OrcaSlicer, PMOVES-OctoPrint-Obico, PMOVES-fluidd. (Note: PMOVES-fluidd does have a valid gitlink 1db9791f — its only defect is the missing branch.)
  4. pmoves/tools/beats_to_voice.py:271 hardcodes out_path = f"/tmp/beats_to_voice_{int(time.time())}.wav" — no tempfile import anywhere in the file. Breaks on native Windows, collides at 1-second resolution, is symlink-predictable, and listen-mode never unlinks it. Threads 1/2/3 and 26 all converge on this one line.

The remaining threads (E2B + Haven/Reticulum handoff briefs, DGX Spark profile, compose tag defaults) are review of documents already merged to main via the dropped commits; they are not reachable from this PR.

@POWERFULMOVES POWERFULMOVES changed the title chore(submodule): promote PMOVES-hermes-agent to hardened tip (49 upstream commits) chore(submodule): promote PMOVES-hermes-agent to hardened tip (42 upstream commits) Aug 10, 2026
@POWERFULMOVES
POWERFULMOVES merged commit f6c7936 into main Aug 12, 2026
19 checks passed
@POWERFULMOVES
POWERFULMOVES deleted the chore/promote-hermes-agent-gitlink-2026-08-10 branch August 12, 2026 11:31
POWERFULMOVES added a commit that referenced this pull request Aug 12, 2026
…ax_score is 110)

_evaluate_model returned "max_score": max_score + 10 (= 110) while
test_hf_services.py asserted max_score == 100 — a deterministic failure the
moment the HF suite's imports resolve. It is currently masked: the whole class
is skipif-guarded and aiohttp is absent, so all 21 tests skip rather than fail.

The code was right and the test was stale. Criteria 1-4 award 40+25+20+15 = 100
and Criterion 5 adds a further +10 compatibility bonus, so 110 is the genuinely
attainable maximum — verified by scoring a model that hits every criterion and
landing on exactly 110. Nothing keys off max_score functionally: MIN_SCORE is an
absolute threshold (50), not a percentage, there is no hf.model.evaluated.v1
schema pinning the field, and the only other reader is a log denominator.

So rather than flip the assertion, the scale is now stated once:

  BASE_MAX_SCORE = 100          # 40 + 25 + 20 + 15
  COMPAT_BONUS_POINTS = 10      # Criterion 5
  MAX_SCORE = BASE_MAX_SCORE + COMPAT_BONUS_POINTS

Criterion 5 and the returned max_score both read those constants, so the
denominator can no longer drift from the rubric that produces it.

Tests assert against the constants, plus new coverage for the bonus itself
(measured as a delta between two otherwise-identical models, so it holds
regardless of the env-derived PREFERRED_TAGS/AVOID_TAGS sets).

Surfaced by the #2511 review (Codex P1); not introduced by it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
POWERFULMOVES added a commit that referenced this pull request Aug 12, 2026
.gitmodules registers PMOVES-ollama (path/url/branch/ignore) but main carried
no mode-160000 entry at that path: 65 registered paths against 64 gitlinks,
with PMOVES-ollama the only orphan.

Not a lost pin — a split landing. #2365 merged the .gitmodules entry, but the
commit that adds the gitlink (5047cec, 'pin PMOVES-ollama gitlink to hardened
HEAD') is still sitting unmerged on the local branch feat/ollama-submodule with
no open PR. This restores that stranded half.

Pin is 8d8c701d6a8a7f4129488d7698e3ae02d24e223c, verified against the remote
rather than copied from the stranded commit:

  git ls-remote .../PMOVES-ollama.git refs/heads/PMOVES.AI-Edition-Hardened
    -> 8d8c701d6a8a7f4129488d7698e3ae02d24e223c

which matches the branch recorded in .gitmodules. Registered paths and gitlinks
are now 65/65 with no orphans.

Surfaced by the #2511 review (CodeRabbit); not introduced by it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
POWERFULMOVES added a commit that referenced this pull request Aug 12, 2026
…licy check goes green

submodule-branch-policy-check was already failing on main — 5 submodules with
no branch field at all and 5 more pinned to a branch the allow-list did not
cover. Missing branch is not cosmetic: validate_submodule_gitlinks.sh skips
branch/ancestry validation for those entries and gitlink-promoter.yml never
discovers them, so they sit outside the hardened update workflow entirely.

The obvious fix is wrong. None of the five maker forks has a
PMOVES.AI-Edition-Hardened branch, so applying SUBMODULE_BRANCH_DEFAULT would
have written five branch names that do not exist — the same defect class as the
#2511 gitlink that prompted this. Each fork has exactly one branch, the upstream
default, confirmed by git ls-remote:

  PMOVES-obico-server     release
  PMOVES-moonraker-obico  master
  PMOVES-OrcaSlicer       main
  PMOVES-OctoPrint-Obico  master
  PMOVES-fluidd           develop

Every gitlink on main already points at exactly that branch's tip, so recording
these is describing reality, not changing what is checked out.

Non-hardened branches go in SUBMODULE_BRANCH_ALLOW, the mechanism already used
for PMOVES-ClawZ=main. The five skills/* forks legitimately track main and are
added the same way; without them the gate stays red and the branch fields above
cannot be verified.

  make -C pmoves submodule-branch-policy-check
    before: FAIL (5 missing branch, 5 policy mismatches)
    after:  PASS - checked: 65

Out of scope, do not fix twice: PR #2493 adds PMOVES-nats-server with no branch
key and is still open, so it will reintroduce a missing-branch failure when it
lands. Its fork tracks main.

Surfaced by the #2511 review (Codex P2 / CodeRabbit); not introduced by it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
POWERFULMOVES added a commit that referenced this pull request Aug 12, 2026
…ax_score is 110)

_evaluate_model returned "max_score": max_score + 10 (= 110) while
test_hf_services.py asserted max_score == 100 — a deterministic failure the
moment the HF suite's imports resolve. It is currently masked: the whole class
is skipif-guarded and aiohttp is absent, so all 21 tests skip rather than fail.

The code was right and the test was stale. Criteria 1-4 award 40+25+20+15 = 100
and Criterion 5 adds a further +10 compatibility bonus, so 110 is the genuinely
attainable maximum — verified by scoring a model that hits every criterion and
landing on exactly 110. Nothing keys off max_score functionally: MIN_SCORE is an
absolute threshold (50), not a percentage, there is no hf.model.evaluated.v1
schema pinning the field, and the only other reader is a log denominator.

So rather than flip the assertion, the scale is now stated once:

  BASE_MAX_SCORE = 100          # 40 + 25 + 20 + 15
  COMPAT_BONUS_POINTS = 10      # Criterion 5
  MAX_SCORE = BASE_MAX_SCORE + COMPAT_BONUS_POINTS

Criterion 5 and the returned max_score both read those constants, so the
denominator can no longer drift from the rubric that produces it.

Tests assert against the constants, plus new coverage for the bonus itself
(measured as a delta between two otherwise-identical models, so it holds
regardless of the env-derived PREFERRED_TAGS/AVOID_TAGS sets).

Surfaced by the #2511 review (Codex P1); not introduced by it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
POWERFULMOVES added a commit that referenced this pull request Aug 12, 2026
.gitmodules registers PMOVES-ollama (path/url/branch/ignore) but main carried
no mode-160000 entry at that path: 65 registered paths against 64 gitlinks,
with PMOVES-ollama the only orphan.

Not a lost pin — a split landing. #2365 merged the .gitmodules entry, but the
commit that adds the gitlink (5047cec, 'pin PMOVES-ollama gitlink to hardened
HEAD') is still sitting unmerged on the local branch feat/ollama-submodule with
no open PR. This restores that stranded half.

Pin is 8d8c701d6a8a7f4129488d7698e3ae02d24e223c, verified against the remote
rather than copied from the stranded commit:

  git ls-remote .../PMOVES-ollama.git refs/heads/PMOVES.AI-Edition-Hardened
    -> 8d8c701d6a8a7f4129488d7698e3ae02d24e223c

which matches the branch recorded in .gitmodules. Registered paths and gitlinks
are now 65/65 with no orphans.

Surfaced by the #2511 review (CodeRabbit); not introduced by it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
POWERFULMOVES added a commit that referenced this pull request Aug 12, 2026
…licy check goes green

submodule-branch-policy-check was already failing on main — 5 submodules with
no branch field at all and 5 more pinned to a branch the allow-list did not
cover. Missing branch is not cosmetic: validate_submodule_gitlinks.sh skips
branch/ancestry validation for those entries and gitlink-promoter.yml never
discovers them, so they sit outside the hardened update workflow entirely.

The obvious fix is wrong. None of the five maker forks has a
PMOVES.AI-Edition-Hardened branch, so applying SUBMODULE_BRANCH_DEFAULT would
have written five branch names that do not exist — the same defect class as the
#2511 gitlink that prompted this. Each fork has exactly one branch, the upstream
default, confirmed by git ls-remote:

  PMOVES-obico-server     release
  PMOVES-moonraker-obico  master
  PMOVES-OrcaSlicer       main
  PMOVES-OctoPrint-Obico  master
  PMOVES-fluidd           develop

Every gitlink on main already points at exactly that branch's tip, so recording
these is describing reality, not changing what is checked out.

Non-hardened branches go in SUBMODULE_BRANCH_ALLOW, the mechanism already used
for PMOVES-ClawZ=main. The five skills/* forks legitimately track main and are
added the same way; without them the gate stays red and the branch fields above
cannot be verified.

  make -C pmoves submodule-branch-policy-check
    before: FAIL (5 missing branch, 5 policy mismatches)
    after:  PASS - checked: 65

Out of scope, do not fix twice: PR #2493 adds PMOVES-nats-server with no branch
key and is still open, so it will reintroduce a missing-branch failure when it
lands. Its fork tracks main.

Surfaced by the #2511 review (Codex P2 / CodeRabbit); not introduced by it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
POWERFULMOVES added a commit that referenced this pull request Aug 12, 2026
…ract, orphan gitlink, branch policy) (#2519)

* fix(hf-research-agent): make the scoring scale one source of truth (max_score is 110)

_evaluate_model returned "max_score": max_score + 10 (= 110) while
test_hf_services.py asserted max_score == 100 — a deterministic failure the
moment the HF suite's imports resolve. It is currently masked: the whole class
is skipif-guarded and aiohttp is absent, so all 21 tests skip rather than fail.

The code was right and the test was stale. Criteria 1-4 award 40+25+20+15 = 100
and Criterion 5 adds a further +10 compatibility bonus, so 110 is the genuinely
attainable maximum — verified by scoring a model that hits every criterion and
landing on exactly 110. Nothing keys off max_score functionally: MIN_SCORE is an
absolute threshold (50), not a percentage, there is no hf.model.evaluated.v1
schema pinning the field, and the only other reader is a log denominator.

So rather than flip the assertion, the scale is now stated once:

  BASE_MAX_SCORE = 100          # 40 + 25 + 20 + 15
  COMPAT_BONUS_POINTS = 10      # Criterion 5
  MAX_SCORE = BASE_MAX_SCORE + COMPAT_BONUS_POINTS

Criterion 5 and the returned max_score both read those constants, so the
denominator can no longer drift from the rubric that produces it.

Tests assert against the constants, plus new coverage for the bonus itself
(measured as a delta between two otherwise-identical models, so it holds
regardless of the env-derived PREFERRED_TAGS/AVOID_TAGS sets).

Surfaced by the #2511 review (Codex P1); not introduced by it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(submodules): add the missing PMOVES-ollama gitlink

.gitmodules registers PMOVES-ollama (path/url/branch/ignore) but main carried
no mode-160000 entry at that path: 65 registered paths against 64 gitlinks,
with PMOVES-ollama the only orphan.

Not a lost pin — a split landing. #2365 merged the .gitmodules entry, but the
commit that adds the gitlink (5047cec, 'pin PMOVES-ollama gitlink to hardened
HEAD') is still sitting unmerged on the local branch feat/ollama-submodule with
no open PR. This restores that stranded half.

Pin is 8d8c701d6a8a7f4129488d7698e3ae02d24e223c, verified against the remote
rather than copied from the stranded commit:

  git ls-remote .../PMOVES-ollama.git refs/heads/PMOVES.AI-Edition-Hardened
    -> 8d8c701d6a8a7f4129488d7698e3ae02d24e223c

which matches the branch recorded in .gitmodules. Registered paths and gitlinks
are now 65/65 with no orphans.

Surfaced by the #2511 review (CodeRabbit); not introduced by it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(submodules): record the real tracked branch for 12 submodules; policy check goes green

submodule-branch-policy-check was already failing on main — 5 submodules with
no branch field at all and 5 more pinned to a branch the allow-list did not
cover. Missing branch is not cosmetic: validate_submodule_gitlinks.sh skips
branch/ancestry validation for those entries and gitlink-promoter.yml never
discovers them, so they sit outside the hardened update workflow entirely.

The obvious fix is wrong. None of the five maker forks has a
PMOVES.AI-Edition-Hardened branch, so applying SUBMODULE_BRANCH_DEFAULT would
have written five branch names that do not exist — the same defect class as the
#2511 gitlink that prompted this. Each fork has exactly one branch, the upstream
default, confirmed by git ls-remote:

  PMOVES-obico-server     release
  PMOVES-moonraker-obico  master
  PMOVES-OrcaSlicer       main
  PMOVES-OctoPrint-Obico  master
  PMOVES-fluidd           develop

Every gitlink on main already points at exactly that branch's tip, so recording
these is describing reality, not changing what is checked out.

Non-hardened branches go in SUBMODULE_BRANCH_ALLOW, the mechanism already used
for PMOVES-ClawZ=main. The five skills/* forks legitimately track main and are
added the same way; without them the gate stays red and the branch fields above
cannot be verified.

  make -C pmoves submodule-branch-policy-check
    before: FAIL (5 missing branch, 5 policy mismatches)
    after:  PASS - checked: 65

Out of scope, do not fix twice: PR #2493 adds PMOVES-nats-server with no branch
key and is still open, so it will reintroduce a missing-branch failure when it
lands. Its fork tracks main.

Surfaced by the #2511 review (Codex P2 / CodeRabbit); not introduced by it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
POWERFULMOVES added a commit that referenced this pull request Aug 18, 2026
…mode cleanup (#2520)

* fix(beats_to_voice): write synthesized audio to a secure temp file and clean it up

Two defects in the same synthesis path.

The output path was the hard-coded literal
/tmp/beats_to_voice_{int(time.time())}.wav, with no tempfile import anywhere in
the file. That is three problems at once:

  - it ignores the platform temp directory. On native Windows /tmp resolves to
    C:\tmp: where that exists (Git Bash provides it) the audio is written to a
    fixed, shared location at the drive root instead of TEMP; where it does not,
    open() raises FileNotFoundError and the broad OSError handler reports it as
    'Connection failed', misattributing a local filesystem error to the network
    and discarding audio that was already synthesized.
  - the name is derived from whole seconds, so two calls in the same second
    silently overwrite each other and can return a path holding another
    request's audio. The new collision test demonstrates this directly: against
    the old code both calls return the identical path.
  - the name is predictable, so a local actor with access to that directory can
    pre-create a symlink there and redirect the write.

Now tempfile.mkstemp(prefix=..., suffix='.wav'), which honours TMPDIR/TEMP,
creates the file 0600, and never returns the same path twice.

Separately, listen mode leaked every file it created. _handler extracts and
publishes the CGP packet and never reads the WAV, so a sustained
voice.agent.response.v1 stream left one file behind per trigger until the disk
filled. The pipeline result is now cleaned up in a finally block, so the audio
is dropped even when publishing raises.

Tests cover both, and were confirmed to fail against the pre-fix module
(7 of 8 fail there, 8 pass here) rather than passing vacuously.

Surfaced by the #2511 review (Codex P1 + P2, CodeRabbit); not introduced by it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(beats_to_voice): only delete tempfiles this process created; clean up failed writes

Two review findings on the listen-mode cleanup, both reproduced as failing tests
before the fix.

P1 — arbitrary deletion. `synthesize_prosodic` returns the decoded JSON body
verbatim when Flute answers with a non-audio content-type, so the `synthesis`
dict — and its `output` value — can come straight from the gateway.
`_discard_synthesized_audio` then unlinked it unconditionally, so a remote or
misconfigured endpoint answering `{"output": "/home/service/data.db"}` gets that
file deleted by the listen loop, as any file the process can write. Cleanup is now
restricted to paths this process created via mkstemp, tracked in
`_OWNED_TEMPFILES` and consumed on use; anything else is refused with a message.

P2 — orphaned tempfiles. mkstemp creates the file before the write, so an OSError
while writing or closing left a zero-byte or partial file behind: the outer
handler returns None, no caller learns a path to clean up, and each retry
allocates a fresh unique name. Failure now closes and unlinks before re-raising.

Closing the descriptor first is load-bearing and cost me a red test: `fdopen`
only takes ownership of the fd when it succeeds, and Windows refuses to unlink a
file that still has an open handle — so unlink alone left the file in place on
exactly the platform this PR exists to support.

Also hardened the chained `.get()` walk: a JSON body need not be an object, and
`{"synthesis": []}` raised AttributeError inside the cleanup path.

All four new tests fail on the pre-fix tool and pass after:

  test_refuses_a_path_this_process_did_not_create  AssertionError: cleanup deleted
      a path the process never created
  test_second_discard_is_a_no_op                   AssertionError
  test_non_dict_synthesis_is_a_no_op               AttributeError: 'list' object
      has no attribute 'get'
  test_failed_write_removes_the_tempfile           AssertionError: the partially-
      written tempfile was left behind

12 passed after. The pre-existing `test_removes_the_synthesized_file` was
rewritten to obtain its path from `synthesize_prosodic` rather than a bare
mkstemp — under the ownership rule, deleting an unowned path is the behaviour
being removed, so a test asserting it would have been asserting the defect.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
POWERFULMOVES pushed a commit that referenced this pull request Aug 18, 2026
…08-18)

The claim register's last SPARK-KIMI entry was 2026-05-27; this session
landed eight lanes that were never registered. One CLAIM+RELEASE entry
registers them with live-main merge verification for each:

- Hermes unblock chain (fork sync #3 + gitlink #2511)
- P7 legacy stanza fix #2549 (+ pr-monitor bot classifier fix)
- PMOVES-crush visual ecosystem (#10/#11 + promotion #2571)
- pmoves-keygen adoption (fork #1 OPEN, parent #2591) — closes the
  pending-ml signing-card gap (24/25 cards h-only)
- #2515 fleet handoffs docs
- Hygiene: 86-commit stack proven landed and retired; 10 worktrees + 5
  stashes cleared; cipher-mcp deletion corrected-to-restore
- ~100GB disk recovery
- P7 migrated to canonical service (13 rooms, NATS connected)

Open follow-ups listed unclaimed for the next lane owners.

💘 Generated with Crush
POWERFULMOVES pushed a commit that referenced this pull request Aug 18, 2026
…08-18)

The claim register's last SPARK-KIMI entry was 2026-05-27; this session
landed eight lanes that were never registered. One CLAIM+RELEASE entry
registers them with live-main merge verification for each:

- Hermes unblock chain (fork sync #3 + gitlink #2511)
- P7 legacy stanza fix #2549 (+ pr-monitor bot classifier fix)
- PMOVES-crush visual ecosystem (#10/#11 + promotion #2571)
- pmoves-keygen adoption (fork #1 OPEN, parent #2591) — closes the
  pending-ml signing-card gap (24/25 cards h-only)
- #2515 fleet handoffs docs
- Hygiene: 86-commit stack proven landed and retired; 10 worktrees + 5
  stashes cleared; cipher-mcp deletion corrected-to-restore
- ~100GB disk recovery
- P7 migrated to canonical service (13 rooms, NATS connected)

Open follow-ups listed unclaimed for the next lane owners.

💘 Generated with Crush
POWERFULMOVES added a commit that referenced this pull request Aug 18, 2026
…08-18) (#2596)

* docs(agents): register the SPARK-KIMI convergence wave (2026-08-10 → 08-18)

The claim register's last SPARK-KIMI entry was 2026-05-27; this session
landed eight lanes that were never registered. One CLAIM+RELEASE entry
registers them with live-main merge verification for each:

- Hermes unblock chain (fork sync #3 + gitlink #2511)
- P7 legacy stanza fix #2549 (+ pr-monitor bot classifier fix)
- PMOVES-crush visual ecosystem (#10/#11 + promotion #2571)
- pmoves-keygen adoption (fork #1 OPEN, parent #2591) — closes the
  pending-ml signing-card gap (24/25 cards h-only)
- #2515 fleet handoffs docs
- Hygiene: 86-commit stack proven landed and retired; 10 worktrees + 5
  stashes cleared; cipher-mcp deletion corrected-to-restore
- ~100GB disk recovery
- P7 migrated to canonical service (13 rooms, NATS connected)

Open follow-ups listed unclaimed for the next lane owners.

💘 Generated with Crush

* docs(agnote): SPARK-KIMI lane refresh — coordination split acknowledged, stale VSS claim released

Claims the active SPARK lanes under the operator's merge/fix split
(4090 merges, Z890 tools, SPARK reviews + registers), and releases the
stale feature/spark-vss-submodule-wiring claim after verifying it landed
via squash #2277.

Generated with Crush

* docs(agnote): correct the Hermes commit count and the SPARK registration gap

Two review findings on the register entry, both verified against source.

Hermes fork-sync #3 advanced 42 upstream commits, not 49. The promotion
commit f6c7936 corrects this in its own body ("42 commits advance on the
hardened branch"); 49 was the original PR title. A provenance register
that preserves a superseded count disagrees with the commit it
summarizes.

The "last SPARK-KIMI entry was 2026-05-27" claim was false. The same
register already holds a SPARK-KIMI claim on 2026-06-01, a CLAIM/RELEASE
pair on 2026-07-13, and KIMI-SPARK activity through 2026-07-29. The real
unregistered interval is 2026-07-29 -> 2026-08-18. Overstating it by two
months would have made lane reconciliation unreliable in exactly the
direction that causes duplicate work.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Agent Zero <agent.zero@pmoves.ai>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
POWERFULMOVES added a commit that referenced this pull request Aug 31, 2026
…2855)

Fork PR #5 (un-strand the pmoves_bootstrap CGP consumer onto PMOVES.AI-Edition-Hardened)
merged. Clean fast-forward (ahead 6, behind 0): 40765f76 -> 4595a549. Every hardened
submodule checkout now ships pmoves_bootstrap (was zero — #2511 had skipped the commit).


Claude-Session: https://claude.ai/code/session_017g8jC7dupS2ubafo6zPQY6

Co-authored-by: Mavis <Mavis@pmoves.local>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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