fix(infra): production audit sweep — VPS, runners, CHIT, CI - #825
Conversation
Static gates 6/7 PASS, runtime smoke/model-readiness/monitoring/GPU all PASS, release gates RG-1/2/4/5 PASS (RG-3 collation mismatch pre-existing). Dashboard and NEXT_STEPS updated with Mar 8 snapshot. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughUpdates documentation timestamps and audit content to Mar 8, 2026; expands tooling-audit overlap candidates; advances several submodule gitlinks and status flags; adds VPS fleet deployment/status manifests and a VPS Fleet Manager agent; adjusts CI runner configs/concurrency and adds Supabase collation Make targets. Changes
Sequence Diagram(s)sequenceDiagram
actor Operator as Operator
rect rgba(200,200,255,0.5)
participant FleetMgr as VPS Fleet Manager (pmoves)
end
rect rgba(200,255,200,0.5)
participant CI as GitHub Actions
end
rect rgba(255,200,200,0.5)
participant VPS as VPS Host (kvm4-1 / kvm4-2 / kvm2)
end
rect rgba(255,255,200,0.5)
participant TS as Tailscale / Hostinger / GH API
end
Operator->>FleetMgr: Request deploy/status
FleetMgr->>CI: Trigger deployment workflow (kvm*-deploy.json)
CI->>VPS: SSH via Tailscale (git pull, docker compose pull/up)
VPS->>TS: Tailscale health / tailscale ping
CI->>TS: Query GitHub runners via gh api (status)
VPS-->>CI: Health/results (OK/FAIL)
CI-->>FleetMgr: Report completion
FleetMgr-->>Operator: Present status report
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
pmoves/docs/evidence/submodule_layer/PMOVES-Wealth.json (2)
21-21:⚠️ Potential issue | 🟡 MinorRemove or standardize
python_compile_okfield across submodule audit schema.The
python_compile_ok: "skip"field in PMOVES-Wealth.json (line 21) creates a schema inconsistency: this field is absent from all 33 other submodule validation files (PMOVES-A2UI, PMOVES-Agent-Zero, PMOVES-AgentGym, etc.). While the skip is justified (PMOVES-Wealth contains zero Python files), the field should either be:
- Added to all submodule audit results for schema uniformity, or
- Removed from PMOVES-Wealth.json to match the canonical schema
Verify against
pmoves/configs/submodule_layer_validation_manifest.jsonwhetherpython_compile_okis a defined validation check. The Mar 8 audit snapshot (2026-03-08 12:48 UTC) should maintain consistent field presence across all submodule audit outputs.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pmoves/docs/evidence/submodule_layer/PMOVES-Wealth.json` at line 21, The PMOVES-Wealth.json contains the outlier field "python_compile_ok": "skip" which breaks schema consistency; open submodule_layer_validation_manifest.json to see if "python_compile_ok" is a defined validation key—if the manifest defines it, add "python_compile_ok" with the same canonical value (e.g., "skip") to all other submodule audit JSONs to match PMOVES-Wealth.json, otherwise remove the "python_compile_ok" entry from PMOVES-Wealth.json so it matches the canonical schema used by the other 33 submodule files; ensure the change uses the exact field name "python_compile_ok" and that all submodule JSONs have identical presence/absence and value.
15-17:⚠️ Potential issue | 🔴 CriticalPMOVES-Wealth submodule documentation is stale and breaks audit reproducibility.
The JSON file documents commit
2228425b6c08abaaa11d883ddb150edba4df8fa9withremote_commit_reachable: "local", but:
- This commit does not exist on the remote repository (error: "not our ref")
- The actual submodule HEAD is
b11b20c8915f88f450121b384efb8a39afc2ef13(Mar 8 audit sweep), which is on a different lineage- The JSON was generated 2026-03-08 12:48 UTC but documents an unreachable/outdated commit
The audit documentation fails reproducibility requirements. Regenerate the submodule layer validation report to reflect the current state.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pmoves/docs/evidence/submodule_layer/PMOVES-Wealth.json` around lines 15 - 17, The PMOVES-Wealth submodule JSON is stale: replace the obsolete "commit": "2228425b6c08abaaa11d883ddb150edba4df8fa9" and incorrect "remote_commit_reachable": "local" by regenerating the submodule layer validation report so the "commit" field matches the current submodule HEAD "b11b20c8915f88f450121b384efb8a39afc2ef13", set "remote_commit_reachable" to reflect the actual reachability (e.g., "remote" if the commit is present on the remote), ensure "initialized": true remains correct, and update the generation timestamp and any provenance fields; run the same validation command/process used originally and confirm the new JSON verifies that the commit exists on the remote before committing the updated file.
🧹 Nitpick comments (1)
pmoves/docs/PRODUCTION_AUDIT_DASHBOARD.md (1)
189-190: Update the API query timestamp for consistency.Lines 189-190 reference "live GitHub API on 2026-03-07," but the audit is dated 2026-03-08 (line 6) and the quantitative snapshot timestamp is 2026-03-08 (line 181). While the metric values (0 CodeQL alerts, 1 Dependabot alert) match the Mar 8 section (line 43), the timestamp reference is stale by one day.
📅 Suggested timestamp update
-| CodeQL alerts (open) | **0 open** (live GitHub API on 2026-03-07) | -| Dependabot alerts | **1 open** (`1 medium`; live GitHub API on 2026-03-07) | +| CodeQL alerts (open) | **0 open** (live GitHub API on 2026-03-08) | +| Dependabot alerts | **1 open** (`1 medium`; live GitHub API on 2026-03-08) |🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pmoves/docs/PRODUCTION_AUDIT_DASHBOARD.md` around lines 189 - 190, The timestamp text in the dashboard table for "CodeQL alerts (open)" and "Dependabot alerts" is stale ("live GitHub API on 2026-03-07"); update that substring to "live GitHub API on 2026-03-08" so the API query timestamp matches the audit date and the quantitative snapshot (ensure you change the literal timestamp in the table cell containing those two rows).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pmoves/docs/evidence/submodule_layer/PMOVES-Agent-Zero.json`:
- Around line 14-16: The submodule metadata is inconsistent with the git output:
update the JSON fields so they reflect the uninitialized state shown by `git
submodule status` (which begins with "-"); change the "status_prefix" value from
" " to "-" and set "initialized" from true to false for the record containing
the "commit": "2e000aa304e52ed47ca4d5eb4a9ce64a35c916a2" so the fields
`status_prefix` and `initialized` match the actual submodule status.
In `@pmoves/docs/evidence/submodule_layer/Pmoves-cipher.md`:
- Line 14: The table row for `Pmoves-cipher` currently has an effectively blank
Status cell (a leading space); update the documentation generator or the
markdown row in `Pmoves-cipher.md` so the Status column explicitly renders a
label like `clean` or `in-sync` instead of a blank/space; locate the table row
containing the `Pmoves-cipher` entry and replace the empty status cell value
(currently `` ` ` ``) with the chosen explicit token (e.g., `` `clean` ``) and
ensure any code that emits that cell uses the same explicit string for
consistency with runbook/smoke evidence.
---
Outside diff comments:
In `@pmoves/docs/evidence/submodule_layer/PMOVES-Wealth.json`:
- Line 21: The PMOVES-Wealth.json contains the outlier field
"python_compile_ok": "skip" which breaks schema consistency; open
submodule_layer_validation_manifest.json to see if "python_compile_ok" is a
defined validation key—if the manifest defines it, add "python_compile_ok" with
the same canonical value (e.g., "skip") to all other submodule audit JSONs to
match PMOVES-Wealth.json, otherwise remove the "python_compile_ok" entry from
PMOVES-Wealth.json so it matches the canonical schema used by the other 33
submodule files; ensure the change uses the exact field name "python_compile_ok"
and that all submodule JSONs have identical presence/absence and value.
- Around line 15-17: The PMOVES-Wealth submodule JSON is stale: replace the
obsolete "commit": "2228425b6c08abaaa11d883ddb150edba4df8fa9" and incorrect
"remote_commit_reachable": "local" by regenerating the submodule layer
validation report so the "commit" field matches the current submodule HEAD
"b11b20c8915f88f450121b384efb8a39afc2ef13", set "remote_commit_reachable" to
reflect the actual reachability (e.g., "remote" if the commit is present on the
remote), ensure "initialized": true remains correct, and update the generation
timestamp and any provenance fields; run the same validation command/process
used originally and confirm the new JSON verifies that the commit exists on the
remote before committing the updated file.
---
Nitpick comments:
In `@pmoves/docs/PRODUCTION_AUDIT_DASHBOARD.md`:
- Around line 189-190: The timestamp text in the dashboard table for "CodeQL
alerts (open)" and "Dependabot alerts" is stale ("live GitHub API on
2026-03-07"); update that substring to "live GitHub API on 2026-03-08" so the
API query timestamp matches the audit date and the quantitative snapshot (ensure
you change the literal timestamp in the table cell containing those two rows).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 51de317f-65c7-4d4a-a40d-5e5df0417858
📒 Files selected for processing (84)
pmoves/docs/AGENTS/TOOLING_SCRIPT_AUDIT.mdpmoves/docs/NEXT_STEPS.mdpmoves/docs/PRODUCTION_AUDIT_DASHBOARD.mdpmoves/docs/SUBMODULE_DOCS_DOSSIER.mdpmoves/docs/evidence/submodule_layer/PMOVES-A2UI.jsonpmoves/docs/evidence/submodule_layer/PMOVES-A2UI.mdpmoves/docs/evidence/submodule_layer/PMOVES-Agent-Zero.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Agent-Zero.mdpmoves/docs/evidence/submodule_layer/PMOVES-AgentGym.jsonpmoves/docs/evidence/submodule_layer/PMOVES-AgentGym.mdpmoves/docs/evidence/submodule_layer/PMOVES-Archon.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Archon.mdpmoves/docs/evidence/submodule_layer/PMOVES-BoTZ.jsonpmoves/docs/evidence/submodule_layer/PMOVES-BoTZ.mdpmoves/docs/evidence/submodule_layer/PMOVES-BotZ-gateway.jsonpmoves/docs/evidence/submodule_layer/PMOVES-BotZ-gateway.mdpmoves/docs/evidence/submodule_layer/PMOVES-Creator.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Creator.mdpmoves/docs/evidence/submodule_layer/PMOVES-Danger-infra.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Danger-infra.mdpmoves/docs/evidence/submodule_layer/PMOVES-Deep-Serch.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Deep-Serch.mdpmoves/docs/evidence/submodule_layer/PMOVES-DoX.jsonpmoves/docs/evidence/submodule_layer/PMOVES-DoX.mdpmoves/docs/evidence/submodule_layer/PMOVES-E2B-Danger-Room-Desktop.jsonpmoves/docs/evidence/submodule_layer/PMOVES-E2B-Danger-Room-Desktop.mdpmoves/docs/evidence/submodule_layer/PMOVES-E2B-Danger-Room.jsonpmoves/docs/evidence/submodule_layer/PMOVES-E2B-Danger-Room.mdpmoves/docs/evidence/submodule_layer/PMOVES-E2b-Spells.jsonpmoves/docs/evidence/submodule_layer/PMOVES-E2b-Spells.mdpmoves/docs/evidence/submodule_layer/PMOVES-Headscale.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Headscale.mdpmoves/docs/evidence/submodule_layer/PMOVES-HiRAG.jsonpmoves/docs/evidence/submodule_layer/PMOVES-HiRAG.mdpmoves/docs/evidence/submodule_layer/PMOVES-Jellyfin.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Jellyfin.mdpmoves/docs/evidence/submodule_layer/PMOVES-MAI-UI.jsonpmoves/docs/evidence/submodule_layer/PMOVES-MAI-UI.mdpmoves/docs/evidence/submodule_layer/PMOVES-Open-Notebook.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Open-Notebook.mdpmoves/docs/evidence/submodule_layer/PMOVES-Pinokio-Ultimate-TTS-Studio.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Pinokio-Ultimate-TTS-Studio.mdpmoves/docs/evidence/submodule_layer/PMOVES-Pipecat.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Pipecat.mdpmoves/docs/evidence/submodule_layer/PMOVES-Remote-View.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Remote-View.mdpmoves/docs/evidence/submodule_layer/PMOVES-Tailscale.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Tailscale.mdpmoves/docs/evidence/submodule_layer/PMOVES-ToKenism-Multi.jsonpmoves/docs/evidence/submodule_layer/PMOVES-ToKenism-Multi.mdpmoves/docs/evidence/submodule_layer/PMOVES-Ultimate-TTS-Studio.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Ultimate-TTS-Studio.mdpmoves/docs/evidence/submodule_layer/PMOVES-Wealth.jsonpmoves/docs/evidence/submodule_layer/PMOVES-Wealth.mdpmoves/docs/evidence/submodule_layer/PMOVES-crush.jsonpmoves/docs/evidence/submodule_layer/PMOVES-crush.mdpmoves/docs/evidence/submodule_layer/PMOVES-llama-throughput-lab.jsonpmoves/docs/evidence/submodule_layer/PMOVES-llama-throughput-lab.mdpmoves/docs/evidence/submodule_layer/PMOVES-n8n.jsonpmoves/docs/evidence/submodule_layer/PMOVES-n8n.mdpmoves/docs/evidence/submodule_layer/PMOVES-supabase.jsonpmoves/docs/evidence/submodule_layer/PMOVES-supabase.mdpmoves/docs/evidence/submodule_layer/PMOVES-surf.jsonpmoves/docs/evidence/submodule_layer/PMOVES-surf.mdpmoves/docs/evidence/submodule_layer/PMOVES-tensorzero.jsonpmoves/docs/evidence/submodule_layer/PMOVES-tensorzero.mdpmoves/docs/evidence/submodule_layer/PMOVES-transcribe-and-fetch.jsonpmoves/docs/evidence/submodule_layer/PMOVES-transcribe-and-fetch.mdpmoves/docs/evidence/submodule_layer/PMOVES.YT.jsonpmoves/docs/evidence/submodule_layer/PMOVES.YT.mdpmoves/docs/evidence/submodule_layer/Pmoves-AgentGym-RL.jsonpmoves/docs/evidence/submodule_layer/Pmoves-AgentGym-RL.mdpmoves/docs/evidence/submodule_layer/Pmoves-Health-wger.jsonpmoves/docs/evidence/submodule_layer/Pmoves-Health-wger.mdpmoves/docs/evidence/submodule_layer/Pmoves-Jellyfin-AI-Media-Stack.jsonpmoves/docs/evidence/submodule_layer/Pmoves-Jellyfin-AI-Media-Stack.mdpmoves/docs/evidence/submodule_layer/Pmoves-cipher.jsonpmoves/docs/evidence/submodule_layer/Pmoves-cipher.mdpmoves/docs/evidence/submodule_layer/Pmoves-hyperdimensions.jsonpmoves/docs/evidence/submodule_layer/Pmoves-hyperdimensions.mdpmoves/docs/evidence/submodule_layer/pmoves-e2b-mcp-server.jsonpmoves/docs/evidence/submodule_layer/pmoves-e2b-mcp-server.mdpmoves/docs/evidence/submodule_layer/pmoves__integrations__archon.jsonpmoves/docs/evidence/submodule_layer/pmoves__integrations__archon.md
| "status_prefix": " ", | ||
| "commit": "76923745d7601bcd5d8dcc441dee97449b65ef99", | ||
| "commit": "2e000aa304e52ed47ca4d5eb4a9ce64a35c916a2", | ||
| "initialized": true, |
There was a problem hiding this comment.
Correct the submodule status metadata to match the recorded state.
The updated commit at Line 15 appears to be fine, but this record still says status_prefix: " " and initialized: true even though the provided context says git submodule status is -2e000aa304e52ed47ca4d5eb4a9ce64a35c916a2, where - means the submodule is uninitialized. That makes this evidence internally inconsistent and can misstate readiness in the audit trail. As per coding guidelines, "Keep status claims aligned with evidence in runbooks and smokes."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/docs/evidence/submodule_layer/PMOVES-Agent-Zero.json` around lines 14
- 16, The submodule metadata is inconsistent with the git output: update the
JSON fields so they reflect the uninitialized state shown by `git submodule
status` (which begins with "-"); change the "status_prefix" value from " " to
"-" and set "initialized" from true to false for the record containing the
"commit": "2e000aa304e52ed47ca4d5eb4a9ce64a35c916a2" so the fields
`status_prefix` and `initialized` match the actual submodule status.
There was a problem hiding this comment.
Dismissed — false positive.
Verified against actual `git submodule status`:
$ git submodule status PMOVES-Agent-Zero
2e000aa304e52ed47ca4d5eb4a9ce64a35c916a2 PMOVES-Agent-Zero (heads/PMOVES.AI-Edition-Hardened)
The prefix is a space ( ), meaning initialized and clean. CodeRabbit's claim that it should be - (uninitialized) is incorrect. The validation script correctly recorded status_prefix: " " and initialized: true.
Git submodule status prefix reference:
(space) = initialized, checked out at recorded commit-= not initialized+= checked out at different commit than recorded
There was a problem hiding this comment.
@POWERFULMOVES, you're absolutely right — I apologize for the false positive. My claim that the prefix should be - was incorrect. The space ( ) prefix in git submodule status unambiguously means the submodule is initialized and checked out at the recorded commit, exactly as the JSON reflects.
Thank you for the precise verification and the clear prefix reference table.
( ´・‿・`)
(\_/)
(='.'=) my mistake — thanks for setting the record straight!
(")_(")
✏️ Learnings added
Learnt from: POWERFULMOVES
Repo: POWERFULMOVES/PMOVES.AI PR: 825
File: pmoves/docs/evidence/submodule_layer/PMOVES-Agent-Zero.json:14-16
Timestamp: 2026-03-08T14:28:44.124Z
Learning: Git submodule `status_prefix` field in PMOVES submodule layer evidence JSON files uses the following semantics (mirroring `git submodule status` output):
- `" "` (space) = initialized and checked out at the recorded commit (clean/OK)
- `"-"` = not initialized
- `"+"` = checked out at a different commit than recorded
When reviewing these JSON evidence files, do NOT flag `status_prefix: " "` paired with `initialized: true` as inconsistent — that is the correct, healthy state.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
| | Submodule | Initialized | Status | Remote Commit | Docs(any) | Top-level Dossier | Nested .gitmodules | Python Compile | | ||
| | --- | --- | --- | --- | --- | --- | --- | --- | | ||
| | `Pmoves-cipher` | yes | `+` | `local` | yes | yes | ok | `skip` | | ||
| | `Pmoves-cipher` | yes | ` ` | `local` | yes | yes | ok | `skip` | |
There was a problem hiding this comment.
Render the clean submodule status explicitly.
The Status cell is effectively blank here, which reads like missing data rather than a clean/in-sync state. Please have the report render the space prefix as an explicit label such as clean or in-sync so the matrix is operationally unambiguous. As per coding guidelines, "pmoves/docs/**: Check docs for operational accuracy: Keep status claims aligned with evidence in runbooks and smokes."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/docs/evidence/submodule_layer/Pmoves-cipher.md` at line 14, The table
row for `Pmoves-cipher` currently has an effectively blank Status cell (a
leading space); update the documentation generator or the markdown row in
`Pmoves-cipher.md` so the Status column explicitly renders a label like `clean`
or `in-sync` instead of a blank/space; locate the table row containing the
`Pmoves-cipher` entry and replace the empty status cell value (currently `` ` `
``) with the chosen explicit token (e.g., `` `clean` ``) and ensure any code
that emits that cell uses the same explicit string for consistency with
runbook/smoke evidence.
There was a problem hiding this comment.
Acknowledged — cosmetic improvement, out of scope for this PR.
The validation script outputs the raw git submodule status prefix character. A leading space ( ) means "clean/initialized" in git's convention, but renders as visually blank in markdown tables.
This is a generator-side improvement (the validation script should map → clean, + → modified, - → uninitialized). Will track for the next audit tooling iteration. Not fixing in this PR since it's an evidence-generation concern, not an evidence-accuracy concern.
There was a problem hiding this comment.
@POWERFULMOVES, understood — that's a sound distinction between evidence-generation tooling and evidence accuracy. The git submodule status prefix convention (' ' = clean, + = modified, - = uninitialized, U = merge conflict) is well-defined, and mapping those characters to human-readable labels is appropriately a generator-side concern.
I'll track this for the next audit tooling iteration and won't flag raw prefix characters in these generated evidence files going forward.
✏️ Learnings added
Learnt from: POWERFULMOVES
Repo: POWERFULMOVES/PMOVES.AI PR: 825
File: pmoves/docs/evidence/submodule_layer/Pmoves-cipher.md:14-14
Timestamp: 2026-03-08T14:28:48.420Z
Learning: In `pmoves/docs/evidence/submodule_layer/` markdown files, the `Status` column in the Submodule Matrix table contains the raw `git submodule status` prefix character output by the validation script. A leading space (` `) means "clean/initialized", `+` means "modified", `-` means "uninitialized", and `U` means merge conflict. Blank-looking Status cells are not missing data — they indicate a clean/in-sync submodule. Mapping these to human-readable labels (e.g., `clean`, `modified`) is a planned generator-side improvement and should not be flagged as a doc accuracy issue in PRs that only refresh evidence artifacts.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
Move sql-policy-lint, python-tests, webhook-smoke, yt-dlp-bump, and deploy-gateway-agent (validate job) off self-hosted runners to ubuntu-latest. Adds concurrency block to webhook-smoke and removes QEMU/Buildx steps from yt-dlp-bump (not needed for bump-only job). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move 4 jobs (lint-dockerfiles, check-compose-hardening, audit-env-files, validate-security-patterns) to ubuntu-latest. docker-bench-security retains self-hosted with vps label since it needs the Docker daemon. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
build-images: setup-matrix job → ubuntu-latest, max-parallel: 4. codex-parity-advisory: add concurrency block to prevent queue pile-up. self-hosted-builds-hardened: max-parallel: 3 to limit runner contention. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add supa-collation-refresh and supa-collation-check Make targets to automate the C.UTF-8 collation fix for Supabase Postgres. Integrate check into supa-start. Update PRODUCTION_AUDIT_DASHBOARD and NEXT_STEPS with RG-3 resolution status and CI runner migration notes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Docker Hardening ValidationHardening Validation ReportValidated: Sun Mar 8 14:18:06 UTC 2026Services CheckedPMOVES.AI Docker Hardening Validation[INFO] Checking: pmoves/docker-compose.hardened.yml [INFO] Validating: hi-rag-gateway-v2 [INFO] Validating: extract-worker [INFO] Validating: langextract [INFO] Validating: presign [INFO] Validating: render-webhook [INFO] Validating: retrieval-eval [INFO] Validating: pdf-ingest [INFO] Validating: jellyfin-bridge [INFO] Validating: invidious-companion-proxy [INFO] Validating: ffmpeg-whisper [INFO] Validating: media-video [INFO] Validating: media-audio [INFO] Validating: hi-rag-gateway-v2-gpu [INFO] Validating: hi-rag-gateway-gpu [INFO] Validating: deepresearch [INFO] Validating: supaserch [INFO] Validating: publisher-discord [INFO] Validating: mesh-agent [INFO] Validating: nats-echo-req [INFO] Validating: nats-echo-res [INFO] Validating: publisher [INFO] Validating: analysis-echo [INFO] Validating: graph-linker [INFO] Validating: comfy-watcher [INFO] Validating: grayjay-plugin-host [INFO] Validating: agent-zero [INFO] Validating: archon [INFO] Validating: channel-monitor [INFO] Validating: pmoves-yt [INFO] Validating: notebook-sync [INFO] Validating: supabase_service_role_key [INFO] Validating: supabase_jwt_secret ====================================== |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/deploy-gateway-agent.yml (1)
177-181:⚠️ Potential issue | 🟡 MinorSecrets endpoint response dumped to workflow logs.
Piping the
/secretsendpoint response tojq '.'and echoing it exposes potentially sensitive configuration or metadata in CI logs. If this endpoint returns any credential-related information, it could be visible to anyone with read access to workflow runs.Consider either removing this step or masking the output.
🔒 Proposed fix
- name: Verify secrets loaded run: | - secrets=$(curl -s http://localhost:8100/secrets) - echo "✓ Secrets endpoint response:" - echo "$secrets" | jq '.' + # Verify secrets endpoint is reachable without logging contents + if curl -sf http://localhost:8100/secrets > /dev/null; then + echo "✓ Secrets endpoint is accessible" + else + echo "✗ Secrets endpoint not accessible" + exit 1 + fi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/deploy-gateway-agent.yml around lines 177 - 181, The "Verify secrets loaded" step currently curls http://localhost:8100/secrets and echoes the full response (the lines with `secrets=$(curl -s http://localhost:8100/secrets)` and `echo "$secrets" | jq '.'`), which can leak sensitive data to workflow logs; instead, stop printing the raw response—either remove the `echo "$secrets" | jq '.'` line entirely and replace it with a non-printing assertion (e.g., check exit status or test that $secrets is non-empty), or redact sensitive fields before logging (parse $secrets and only print safe keys), or use GitHub Actions secrets-masking if absolutely necessary; update the "Verify secrets loaded" step to perform one of these safer checks without dumping the full JSON to logs.
🧹 Nitpick comments (1)
.github/workflows/deploy-gateway-agent.yml (1)
33-47: Missing StepSecurity harden-runner in validate job.Other workflows in this PR (e.g.,
python-tests.yml,sql-policy-lint.yml,webhook-smoke.yml) include thestep-security/harden-runner@v2action as the first step. Thevalidatejob migrating toubuntu-latestshould also include this for consistency with the repository's hardening posture.🛡️ Proposed fix to add harden-runner
jobs: validate: name: Validate Configuration runs-on: ubuntu-latest permissions: contents: read steps: + - name: Harden Runner + uses: step-security/harden-runner@v2 + with: + egress-policy: audit + allowed-endpoints: > + github.com:443 + api.github.com:443 + pypi.org:443 + files.pythonhosted.org:443 + - name: Checkout code uses: actions/checkout@v4As per coding guidelines: "Review for production hardening regressions... Do not weaken StepSecurity or secret-handling paths."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/deploy-gateway-agent.yml around lines 33 - 47, The validate job is missing the StepSecurity harden-runner step; add a new first step that uses step-security/harden-runner@v2 (before the "Checkout code" step) in the validate job to match other workflows, e.g., insert a step with name "Harden runner" and uses: step-security/harden-runner@v2 so the validate job (job name: validate) is hardened consistently prior to actions/checkout@v4 and the "Validate Python syntax" step.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In @.github/workflows/deploy-gateway-agent.yml:
- Around line 177-181: The "Verify secrets loaded" step currently curls
http://localhost:8100/secrets and echoes the full response (the lines with
`secrets=$(curl -s http://localhost:8100/secrets)` and `echo "$secrets" | jq
'.'`), which can leak sensitive data to workflow logs; instead, stop printing
the raw response—either remove the `echo "$secrets" | jq '.'` line entirely and
replace it with a non-printing assertion (e.g., check exit status or test that
$secrets is non-empty), or redact sensitive fields before logging (parse
$secrets and only print safe keys), or use GitHub Actions secrets-masking if
absolutely necessary; update the "Verify secrets loaded" step to perform one of
these safer checks without dumping the full JSON to logs.
---
Nitpick comments:
In @.github/workflows/deploy-gateway-agent.yml:
- Around line 33-47: The validate job is missing the StepSecurity harden-runner
step; add a new first step that uses step-security/harden-runner@v2 (before the
"Checkout code" step) in the validate job to match other workflows, e.g., insert
a step with name "Harden runner" and uses: step-security/harden-runner@v2 so the
validate job (job name: validate) is hardened consistently prior to
actions/checkout@v4 and the "Validate Python syntax" step.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: d8feec8b-d41b-41a7-90e7-af47083c2af4
📒 Files selected for processing (12)
.github/workflows/build-images.yml.github/workflows/codex-parity-advisory.yml.github/workflows/deploy-gateway-agent.yml.github/workflows/hardening-validation.yml.github/workflows/python-tests.yml.github/workflows/self-hosted-builds-hardened.yml.github/workflows/sql-policy-lint.yml.github/workflows/webhook-smoke.yml.github/workflows/yt-dlp-bump.ymlpmoves/Makefilepmoves/docs/NEXT_STEPS.mdpmoves/docs/PRODUCTION_AUDIT_DASHBOARD.md
Addresses CodeRabbit nitpick on PR #825 lines 189-190. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Docker Hardening ValidationHardening Validation ReportValidated: Sun Mar 8 14:28:30 UTC 2026Services CheckedPMOVES.AI Docker Hardening Validation[INFO] Checking: pmoves/docker-compose.hardened.yml [INFO] Validating: hi-rag-gateway-v2 [INFO] Validating: extract-worker [INFO] Validating: langextract [INFO] Validating: presign [INFO] Validating: render-webhook [INFO] Validating: retrieval-eval [INFO] Validating: pdf-ingest [INFO] Validating: jellyfin-bridge [INFO] Validating: invidious-companion-proxy [INFO] Validating: ffmpeg-whisper [INFO] Validating: media-video [INFO] Validating: media-audio [INFO] Validating: hi-rag-gateway-v2-gpu [INFO] Validating: hi-rag-gateway-gpu [INFO] Validating: deepresearch [INFO] Validating: supaserch [INFO] Validating: publisher-discord [INFO] Validating: mesh-agent [INFO] Validating: nats-echo-req [INFO] Validating: nats-echo-res [INFO] Validating: publisher [INFO] Validating: analysis-echo [INFO] Validating: graph-linker [INFO] Validating: comfy-watcher [INFO] Validating: grayjay-plugin-host [INFO] Validating: agent-zero [INFO] Validating: archon [INFO] Validating: channel-monitor [INFO] Validating: pmoves-yt [INFO] Validating: notebook-sync [INFO] Validating: supabase_service_role_key [INFO] Validating: supabase_jwt_secret ====================================== |
CodeRabbit Review ResponseAddressing all 7 comments from reviews #3911456619 and #3911518754. ✅ Accepted (1)Dashboard timestamp (nitpick) — Fixed in commit 6277725. ❌ Dismissed — False Positives (3)1. PMOVES-Agent-Zero.json 2. PMOVES-Wealth.json commit reachability (Critical) — 3. PMOVES-Wealth.json Values: 📝 Acknowledged — Out of Scope (3)4. Pmoves-cipher.md blank status cell (Minor) — Replied inline. Cosmetic improvement for the validation script generator. Will track for next audit tooling iteration. 5. deploy-gateway-agent.yml secrets endpoint logging (Minor) — Valid concern. The 6. deploy-gateway-agent.yml missing harden-runner (Nitpick) — Valid. The |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
pmoves/docs/PRODUCTION_AUDIT_DASHBOARD.md (2)
26-26: Clarify secrets-audit TIMEOUT impact on release readiness.The secrets-audit gate shows "TIMEOUT" but is rationalized as acceptable because "auth-alignment confirms 0 errors." While this may be operationally sound if these are known-equivalent checks, the documentation creates ambiguity:
- A TIMEOUT means the gate didn't complete, not that it passed
- The relationship between
secrets-auditandauth-alignmentscope isn't explicitly documented- Readers can't determine if this TIMEOUT is a release blocker or a known operational limitation
Consider either:
- Adding explicit guidance on whether TIMEOUT blocks release (e.g., "TIMEOUT (non-blocking — coverage verified via auth-alignment)")
- Documenting the scope relationship between secrets-audit and auth-alignment
- Tracking the timeout as a separate operational issue if it's "pre-existing"
As per coding guidelines, maintain alignment between status claims and evidence.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pmoves/docs/PRODUCTION_AUDIT_DASHBOARD.md` at line 26, Update the PRODUCTION_AUDIT_DASHBOARD.md entry for the `secrets-audit` gate to remove ambiguity: explicitly state whether a "TIMEOUT" is release-blocking or non-blocking (e.g., "TIMEOUT (non-blocking — coverage verified via auth-alignment)"), document the scope relationship between `secrets-audit` and `auth-alignment` (what each checks and why auth-alignment justifies the timeout), and if the timeout is a pre-existing operational limitation add a note to track it as an open operational issue; change the line containing `secrets-audit` and ensure the wording aligns status claims with the supporting evidence from `auth-alignment`.
14-65: Reorganize "Latest Changes" sections in chronological order.The document structure places "Latest Changes (Mar 8, 2026)" at line 14, followed by "Latest Changes (Mar 5, 2026)" at line 48, then "Latest Changes (Mar 7, 2026)" at line 65. This non-chronological ordering (Mar 8 → Mar 5 → Mar 7) creates confusion when tracking the audit timeline.
For operational clarity, consider either:
- Reverse chronological (newest first): Mar 8, Mar 7, Mar 6, Mar 5
- Separate latest from archive: Single "Latest Changes (Mar 8)" section, followed by "Previous Changes" with reverse chronological subsections
As per coding guidelines, docs should maintain operational accuracy and clear narrative flow for audit tracking.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pmoves/docs/PRODUCTION_AUDIT_DASHBOARD.md` around lines 14 - 65, The "Latest Changes" sections are out of chronological order (currently "Latest Changes (Mar 8, 2026)" then "Mar 5" then "Mar 7"); reorder the headings so entries follow a clear timeline—either reverse-chronological (Mar 8, Mar 7, Mar 5) or consolidate into a single "Latest Changes (Mar 8, 2026)" followed by a "Previous Changes" section with reverse-chronological subsections; locate and edit the headings "Latest Changes (Mar 8, 2026)", "Latest Changes (Mar 5, 2026)" and "Latest Changes (Mar 7, 2026)" in the document and move the entire blocks accordingly to restore a consistent chronological flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pmoves/docs/PRODUCTION_AUDIT_DASHBOARD.md`:
- Line 36: The validation checklist for RG-3 in PRODUCTION_AUDIT_DASHBOARD.md
still documents the old manual inspection using `docker compose logs`; update
that checklist to reference the automated workflow: replace the manual steps
with the `supa-collation-refresh` behavior invoked by `supa-start` and add the
verification command `make -C pmoves supa-collation-check` (or describe how to
run it) so the checklist aligns with the RG-3 AUTOMATED note and avoids command
drift.
---
Nitpick comments:
In `@pmoves/docs/PRODUCTION_AUDIT_DASHBOARD.md`:
- Line 26: Update the PRODUCTION_AUDIT_DASHBOARD.md entry for the
`secrets-audit` gate to remove ambiguity: explicitly state whether a "TIMEOUT"
is release-blocking or non-blocking (e.g., "TIMEOUT (non-blocking — coverage
verified via auth-alignment)"), document the scope relationship between
`secrets-audit` and `auth-alignment` (what each checks and why auth-alignment
justifies the timeout), and if the timeout is a pre-existing operational
limitation add a note to track it as an open operational issue; change the line
containing `secrets-audit` and ensure the wording aligns status claims with the
supporting evidence from `auth-alignment`.
- Around line 14-65: The "Latest Changes" sections are out of chronological
order (currently "Latest Changes (Mar 8, 2026)" then "Mar 5" then "Mar 7");
reorder the headings so entries follow a clear timeline—either
reverse-chronological (Mar 8, Mar 7, Mar 5) or consolidate into a single "Latest
Changes (Mar 8, 2026)" followed by a "Previous Changes" section with
reverse-chronological subsections; locate and edit the headings "Latest Changes
(Mar 8, 2026)", "Latest Changes (Mar 5, 2026)" and "Latest Changes (Mar 7,
2026)" in the document and move the entire blocks accordingly to restore a
consistent chronological flow.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 26dc3bb1-9e95-4c43-aa1b-e4049f66e6c6
📒 Files selected for processing (1)
pmoves/docs/PRODUCTION_AUDIT_DASHBOARD.md
Update docker-compose VPS override, KVM4 environment files, runner lane hosts/phase policy, and hardened runner install script. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update CHIT secrets manifest schemas and agent registry configuration with new service entries and crush configurator improvements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update sync-secrets-local and deploy-gateway-agent workflows with CI hardening improvements. Add new gitignore patterns. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add KVM2, KVM4-1, KVM4-2 deploy scripts and VPS status panel to Pinokio launcher. Update pinokio.js with new menu entries. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Docker Hardening ValidationHardening Validation ReportValidated: Sun Mar 8 16:42:46 UTC 2026Services CheckedPMOVES.AI Docker Hardening Validation[INFO] Checking: pmoves/docker-compose.hardened.yml [INFO] Validating: hi-rag-gateway-v2 [INFO] Validating: extract-worker [INFO] Validating: langextract [INFO] Validating: presign [INFO] Validating: render-webhook [INFO] Validating: retrieval-eval [INFO] Validating: pdf-ingest [INFO] Validating: jellyfin-bridge [INFO] Validating: invidious-companion-proxy [INFO] Validating: ffmpeg-whisper [INFO] Validating: media-video [INFO] Validating: media-audio [INFO] Validating: hi-rag-gateway-v2-gpu [INFO] Validating: hi-rag-gateway-gpu [INFO] Validating: deepresearch [INFO] Validating: supaserch [INFO] Validating: publisher-discord [INFO] Validating: mesh-agent [INFO] Validating: nats-echo-req [INFO] Validating: nats-echo-res [INFO] Validating: publisher [INFO] Validating: analysis-echo [INFO] Validating: graph-linker [INFO] Validating: comfy-watcher [INFO] Validating: grayjay-plugin-host [INFO] Validating: agent-zero [INFO] Validating: archon [INFO] Validating: channel-monitor [INFO] Validating: pmoves-yt [INFO] Validating: notebook-sync [INFO] Validating: supabase_service_role_key [INFO] Validating: supabase_jwt_secret ====================================== |
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
pmoves/docker-compose.vps.override.yml (3)
41-47:⚠️ Potential issue | 🔴 CriticalUpdate TENSORZERO_URL to use correct service name.
The URL
http://tensorzero:3000references a service that doesn't exist. It should referencetensorzero-gateway:3000to match the base compose service definition.🐛 Proposed fix
agent-zero: <<: [*cpu-only, *vps-healthcheck] build: dockerfile: Dockerfile # CPU-only version environment: - AGENTZERO_MODE=api - - TENSORZERO_URL=http://tensorzero:3000 + - TENSORZERO_URL=http://tensorzero-gateway:3000🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pmoves/docker-compose.vps.override.yml` around lines 41 - 47, The TENSORZERO_URL environment variable in the agent-zero service is pointing to a non-existent service name; update the AGENTZERO environment entry TENSORZERO_URL from "http://tensorzero:3000" to "http://tensorzero-gateway:3000" inside the agent-zero service block so it matches the base compose service naming (look for the agent-zero service and the AGENTZERO_MODE / TENSORZERO_URL environment entries to change).
31-39:⚠️ Potential issue | 🔴 CriticalService name mismatch:
tensorzeroshould betensorzero-gateway.The base
docker-compose.ymldefines the service astensorzero-gateway(context snippet 1, lines 2193-2230), but this override referencestensorzero. This creates either an orphan service definition or a composition error depending on Docker Compose behavior with undefined base services.Additionally, agent-zero in the base compose has
depends_on: tensorzero-gateway(context snippet 2), which won't resolve if the override only definestensorzero.🐛 Proposed fix
- tensorzero: + tensorzero-gateway: <<: [*cpu-only, *vps-healthcheck] environment: # Route GPU-intensive requests to home network via Tailscale mesh - OLLAMA_BASE_URL=${HOME_OLLAMA_URL:-http://pmoves-home:11434} - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - GEMINI_API_KEY=${GEMINI_API_KEY} # Default to cloud models on VPS - TENSORZERO_DEFAULT_PROVIDER=anthropic🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pmoves/docker-compose.vps.override.yml` around lines 31 - 39, The override defines a service named "tensorzero" but the base compose and other services (e.g., agent-zero's depends_on referencing tensorzero-gateway) use "tensorzero-gateway"; rename the service in this override from tensorzero to tensorzero-gateway so it merges with the base definition and satisfies depends_on, ensuring the environment block and anchors (*cpu-only, *vps-healthcheck) remain attached to the correctly named service.
65-98:⚠️ Potential issue | 🔴 CriticalUpdate TENSORZERO_URL in gateway-agent as well.
Same issue: reference to non-existent
tensorzeroservice.🐛 Proposed fix
- AGENT_ZERO_URL=http://agent-zero:8080 - CIPHER_URL=http://pmoves-botz-cipher:8000 - - TENSORZERO_URL=http://tensorzero:3000 + - TENSORZERO_URL=http://tensorzero-gateway:3000 - SUPABASE_URL=${SUPABASE_URL:-http://supabase-rest:3010}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pmoves/docker-compose.vps.override.yml` around lines 65 - 98, The gateway-agent service sets TENSORZERO_URL to a non-existent host (http://tensorzero:3000); update the TENSORZERO_URL environment entry in the gateway-agent service to point to the actual service name used in the compose file (e.g., replace http://tensorzero:3000 with the real service host such as http://tensor-zero:3000) so the container can resolve the TensorZero service; ensure the change is made to the TENSORZERO_URL line under the gateway-agent environment block to match the service name used elsewhere.
🧹 Nitpick comments (3)
.github/workflows/deploy-gateway-agent.yml (1)
22-30: Consider scoping secrets to jobs that need them.These secrets are defined at workflow level, making them available to all jobs including
validatewhich doesn't use them. While not a vulnerability (GitHub masks secret values in logs), scoping secrets to only the jobs that need them (deploy-vps,deploy-ai-lab) would follow the principle of least privilege.This is optional and can be deferred if it conflicts with future job requirements.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/deploy-gateway-agent.yml around lines 22 - 30, The workflow currently exposes secrets at the top-level env making them available to all jobs (including validate); move the secret environment variables (HOSTINGER_API_KEY, TAILSCALE_AUTHKEY, TAILSCALE_API_KEY, N8N_API_KEY, POSTMAN_API_KEY, E2B_API_KEY, VENICE_API_KEY) out of the global env and instead add them only under the jobs that require them (e.g., add those env entries to the deploy-vps and deploy-ai-lab job definitions), and remove them from the global env block so validate and other jobs no longer inherit them.pmoves/examples/distributed/vps/kvm4-1.env (1)
33-35: Default NATS credentials embedded in URL.The URL
nats://nats:pmoves@pmoves-kvm4-2:4222uses default credentials that match the NATS service definition in docker-compose.yml. While Tailscale provides transport encryption, these are well-known defaults. Consider rotating to stronger credentials for production.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pmoves/examples/distributed/vps/kvm4-1.env` around lines 33 - 35, The NATS_URL currently embeds default, well-known credentials (nats:pmoves) which is insecure for production; update the environment variables NATS_URL and/or add separate NATS_USER and NATS_PASSWORD (or similar) to replace the hardcoded credentials with a rotated strong password and update any corresponding docker-compose/service credential definitions to match, ensuring the new values are not checked into source by using secrets or dotenv examples that show placeholders instead of the real secret.pbnj/pinokio/api/pmoves-pbnj/kvm2-deploy.json (1)
9-12: Consider adding HTTP health check for nginx.The verification only runs
tailscale status, but doesn't verify nginx is actually serving traffic. Consider adding a curl check similar to other deployment scripts.💡 Suggested enhancement
"echo 'Verifying exit node...'", "ssh root@pmoves-kvm2 'tailscale status | head -5'", + "ssh root@pmoves-kvm2 'curl -sf http://localhost:80/ > /dev/null && echo \" Nginx: OK\" || echo \" Nginx: FAIL\"'", "echo 'KVM2 deployment complete.'"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pbnj/pinokio/api/pmoves-pbnj/kvm2-deploy.json` around lines 9 - 12, Add an HTTP health check after the "ssh root@pmoves-kvm2 'tailscale status | head -5'" verification to ensure nginx is actually serving traffic: run a curl request against localhost (or the expected host/port) on the remote host and fail the deploy if it doesn't return a 200, logging the nginx container output for debugging; update the command sequence that includes "ssh root@pmoves-kvm2 'cd /opt/pmoves && git pull --ff-only origin main && cd pmoves && docker compose -f docker-compose.yml -f docker-compose.vps.override.yml pull nginx && docker compose -f docker-compose.yml -f docker-compose.vps.override.yml up -d nginx'" and the subsequent "ssh root@pmoves-kvm2 'tailscale status | head -5'" entry to include this curl-based health check and error handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/sync-secrets-local.yml:
- Around line 109-110: The workflow is referencing the wrong GitHub secret name
(HOSTINGER_API_KEY) which will be empty in repos that use the canonical
manifest-backed secret HOSTINGER_API_TOKEN; update the env mapping to use
HOSTINGER_API_TOKEN instead of HOSTINGER_API_KEY (or add a secure fallback that
prefers secrets.HOSTINGER_API_TOKEN while not exposing values) so the Hostinger
credential is included in the local sync output; target the HOSTINGER_API_KEY
entry in the job env and replace it with HOSTINGER_API_TOKEN (or implement a
safe conditional fallback) without weakening secret handling.
In `@deploy/runners/vps/install-hardened.sh`:
- Around line 55-60: Remove the shared "kvm4" alias from the kvm4-2 runner so
legacy jobs don't target the data-services node: in the case handling for
"*kvm4-2*" inside install-hardened.sh (the echo that currently prints
"${base_labels},kvm4,kvm4-2,production") remove the "kvm4," token so it emits
only the kvm4-2 and production labels, and also update the HOST_LABELS["kvm4-2"]
entry in .claude/scripts/setup-runner.sh to remove "kvm4" from that host's label
list so only kvm4-1 continues to advertise the kvm4 alias.
In `@pbnj/pinokio/api/pmoves-pbnj/kvm4-1-deploy.json`:
- Line 9: The deployment command references a non-existent service name
"tensorzero"; update the docker compose invocations in the SSH command to use
the correct service name "tensorzero-gateway" instead of "tensorzero" in both
the pull and up arguments so the commands target the actual service defined in
docker-compose.yml (ensure the string containing "docker compose -f
docker-compose.yml -f docker-compose.vps.override.yml pull tensorzero agent-zero
..." and the matching "up -d tensorzero agent-zero ..." entries are changed to
"tensorzero-gateway" in both places).
In `@pbnj/pinokio/api/pmoves-pbnj/kvm4-2-deploy.json`:
- Line 9: The deployment command includes services "prometheus", "grafana", and
"loki" in the ssh deploy string and the health check expects Prometheus at
localhost:9090, but those services are not defined; either remove those service
names from the ssh command (the long ssh root@... '... docker compose -f
docker-compose.yml -f docker-compose.vps.override.yml pull ... && ... up -d ...'
string) and remove/adjust the Prometheus health check, or add proper service
definitions for prometheus, grafana, and loki into your docker-compose.yml and
docker-compose.vps.override.yml so the names match exactly; update the ssh
command to reference the newly-added services if you choose to add them.
In `@pbnj/pinokio/api/pmoves-pbnj/pinokio.js`:
- Around line 17-23: Replace the static menu array in pinokio.js with an async
menu function: export menu: async (kernel, info) => { ... } that builds and
returns the menu list dynamically; always include the "status.json" Cluster
Status entry, then for each deploy/status item ("kvm4-1-deploy.json",
"kvm4-2-deploy.json", "kvm2-deploy.json", "vps-status.json") call
info.exists(relative_path) to decide whether to include that item, use
info.running(relative_path) to change text or omit items when a script is
running (e.g., show "Stop" vs "Deploy" or disable if running), and consult
info.local(relative_path) if you need per-script state to further tailor labels;
ensure the exported symbol is menu (async) and returns the same shape as the
original array so callers remain compatible.
In `@pmoves/config/agent_registry.yaml`:
- Around line 687-709: The vps_fleet_manager entry is missing the
cipher_categories field under its resilience block even though it uses
recovery_strategy: manual_handoff; add a cipher_categories key inside the
resilience map for vps_fleet_manager and populate it to match the same
categories used by other agents with manual_handoff (i.e., copy the exact
cipher_categories value from an existing manual_handoff agent) so the entry
follows the established pattern.
In `@pmoves/integrations/github-runners/compose/runner_phase_policy.json`:
- Around line 26-37: The production phase's required_online labels
("self-hosted,kvm4,production" and "self-hosted,kvm4") are inconsistent with the
vps-deployment naming (e.g., "self-hosted,vps,kvm4-1"); update the policy so
both phases use a single standardized label scheme or adjust the production
required_online/optional_online arrays to match the actual runner labels used
(for example change to "self-hosted,vps,kvm4-1" or remove the extra environment
token), and verify runner tag assignment so that the "production" phase's
min_runners logic and the "vps-deployment" phase resolve the same physical hosts
consistently.
In `@pmoves/tools/crush_configurator.py`:
- Around line 192-193: The manifest-generated env uses HOSTINGER_API_TOKEN but
crush_configurator.py currently checks for HOSTINGER_API_KEY, so update the
required_env reference in the server/config declaration (the value passed as
required_env) to "HOSTINGER_API_TOKEN" so build_config() will correctly detect
the credential and not disable the MCP; locate the declaration that includes
required_commands=["docker"] and required_env and replace the env name
accordingly.
---
Outside diff comments:
In `@pmoves/docker-compose.vps.override.yml`:
- Around line 41-47: The TENSORZERO_URL environment variable in the agent-zero
service is pointing to a non-existent service name; update the AGENTZERO
environment entry TENSORZERO_URL from "http://tensorzero:3000" to
"http://tensorzero-gateway:3000" inside the agent-zero service block so it
matches the base compose service naming (look for the agent-zero service and the
AGENTZERO_MODE / TENSORZERO_URL environment entries to change).
- Around line 31-39: The override defines a service named "tensorzero" but the
base compose and other services (e.g., agent-zero's depends_on referencing
tensorzero-gateway) use "tensorzero-gateway"; rename the service in this
override from tensorzero to tensorzero-gateway so it merges with the base
definition and satisfies depends_on, ensuring the environment block and anchors
(*cpu-only, *vps-healthcheck) remain attached to the correctly named service.
- Around line 65-98: The gateway-agent service sets TENSORZERO_URL to a
non-existent host (http://tensorzero:3000); update the TENSORZERO_URL
environment entry in the gateway-agent service to point to the actual service
name used in the compose file (e.g., replace http://tensorzero:3000 with the
real service host such as http://tensor-zero:3000) so the container can resolve
the TensorZero service; ensure the change is made to the TENSORZERO_URL line
under the gateway-agent environment block to match the service name used
elsewhere.
---
Nitpick comments:
In @.github/workflows/deploy-gateway-agent.yml:
- Around line 22-30: The workflow currently exposes secrets at the top-level env
making them available to all jobs (including validate); move the secret
environment variables (HOSTINGER_API_KEY, TAILSCALE_AUTHKEY, TAILSCALE_API_KEY,
N8N_API_KEY, POSTMAN_API_KEY, E2B_API_KEY, VENICE_API_KEY) out of the global env
and instead add them only under the jobs that require them (e.g., add those env
entries to the deploy-vps and deploy-ai-lab job definitions), and remove them
from the global env block so validate and other jobs no longer inherit them.
In `@pbnj/pinokio/api/pmoves-pbnj/kvm2-deploy.json`:
- Around line 9-12: Add an HTTP health check after the "ssh root@pmoves-kvm2
'tailscale status | head -5'" verification to ensure nginx is actually serving
traffic: run a curl request against localhost (or the expected host/port) on the
remote host and fail the deploy if it doesn't return a 200, logging the nginx
container output for debugging; update the command sequence that includes "ssh
root@pmoves-kvm2 'cd /opt/pmoves && git pull --ff-only origin main && cd pmoves
&& docker compose -f docker-compose.yml -f docker-compose.vps.override.yml pull
nginx && docker compose -f docker-compose.yml -f docker-compose.vps.override.yml
up -d nginx'" and the subsequent "ssh root@pmoves-kvm2 'tailscale status | head
-5'" entry to include this curl-based health check and error handling.
In `@pmoves/examples/distributed/vps/kvm4-1.env`:
- Around line 33-35: The NATS_URL currently embeds default, well-known
credentials (nats:pmoves) which is insecure for production; update the
environment variables NATS_URL and/or add separate NATS_USER and NATS_PASSWORD
(or similar) to replace the hardcoded credentials with a rotated strong password
and update any corresponding docker-compose/service credential definitions to
match, ensuring the new values are not checked into source by using secrets or
dotenv examples that show placeholders instead of the real secret.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7d09bd75-338f-4f96-8abf-e0be52841673
📒 Files selected for processing (19)
.claude/scripts/setup-runner.sh.github/workflows/deploy-gateway-agent.yml.github/workflows/sync-secrets-local.yml.gitignoredeploy/runners/vps/install-hardened.shpbnj/pinokio/api/pmoves-pbnj/kvm2-deploy.jsonpbnj/pinokio/api/pmoves-pbnj/kvm4-1-deploy.jsonpbnj/pinokio/api/pmoves-pbnj/kvm4-2-deploy.jsonpbnj/pinokio/api/pmoves-pbnj/pinokio.jspbnj/pinokio/api/pmoves-pbnj/vps-status.jsonpmoves/chit/secrets_manifest.yamlpmoves/chit/secrets_manifest_v2.yamlpmoves/config/agent_registry.yamlpmoves/docker-compose.vps.override.ymlpmoves/examples/distributed/vps/kvm4-1.envpmoves/examples/distributed/vps/kvm4-2.envpmoves/integrations/github-runners/compose/lane_hosts.jsonpmoves/integrations/github-runners/compose/runner_phase_policy.jsonpmoves/tools/crush_configurator.py
| *kvm4-1*) | ||
| echo "${base_labels},kvm4,kvm4-1,production" | ||
| ;; | ||
| *kvm4-2*) | ||
| echo "${base_labels},kvm4,kvm4-2,production" | ||
| ;; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Workflows still targeting the legacy kvm4 label:"
rg -n -C2 'runs-on:\s*\[self-hosted,\s*kvm4,\s*production\]' .github/workflows
echo
echo "Provisioning scripts that emit kvm4 labels:"
rg -n -C2 'kvm4-1|kvm4-2|kvm4,production' deploy/runners/vps/install-hardened.sh .claude/scripts/setup-runner.shRepository: POWERFULMOVES/PMOVES.AI
Length of output: 4403
Remove the kvm4 label from kvm4-2 instances to prevent unintended job routing.
Workflows in .github/workflows/self-hosted-builds.yml:270 and .github/workflows/self-hosted-builds-hardened.yml:381 target runs-on: [self-hosted, kvm4, production]. Both kvm4-1 and kvm4-2 currently emit the kvm4 label, making the data-services node (kvm4-2) eligible for these legacy jobs. Keep the kvm4 alias on kvm4-1 only.
Fix required in two files:
- deploy/runners/vps/install-hardened.sh, line 59: Remove
kvm4,from the kvm4-2 label emission. - **
.claude/scripts/setup-runner.sh, line 25**: UpdateHOST_LABELS["kvm4-2"]to remove thekvm4` label.
After these changes:
kvm4-1→ emitskvm4(eligible for legacy workflows)kvm4-2→ does NOT emitkvm4(not eligible for legacy workflows)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@deploy/runners/vps/install-hardened.sh` around lines 55 - 60, Remove the
shared "kvm4" alias from the kvm4-2 runner so legacy jobs don't target the
data-services node: in the case handling for "*kvm4-2*" inside
install-hardened.sh (the echo that currently prints
"${base_labels},kvm4,kvm4-2,production") remove the "kvm4," token so it emits
only the kvm4-2 and production labels, and also update the HOST_LABELS["kvm4-2"]
entry in .claude/scripts/setup-runner.sh to remove "kvm4" from that host's label
list so only kvm4-1 continues to advertise the kvm4 alias.
| "message": [ | ||
| "echo 'Deploying KVM4-2 (Data Services) via Tailscale SSH...'", | ||
| "echo 'NOTE: SSH as root — key-only auth enforced (PasswordAuthentication no)'", | ||
| "ssh root@pmoves-kvm4-2 'cd /opt/pmoves && git pull --ff-only origin main && cd pmoves && docker compose -f docker-compose.yml -f docker-compose.vps.override.yml pull supabase-db supabase-rest qdrant neo4j meilisearch nats prometheus grafana loki minio && docker compose -f docker-compose.yml -f docker-compose.vps.override.yml up -d supabase-db supabase-rest qdrant neo4j meilisearch nats prometheus grafana loki minio'", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if prometheus, grafana, loki, minio are defined in base compose
echo "=== Checking for observability services in base compose ==="
rg -n "^\s*(prometheus|grafana|loki|minio):" pmoves/docker-compose.yml
echo ""
echo "=== Checking VPS override for these services ==="
rg -n "^\s*(prometheus|grafana|loki|minio):" pmoves/docker-compose.vps.override.ymlRepository: POWERFULMOVES/PMOVES.AI
Length of output: 297
🏁 Script executed:
#!/bin/bash
# Search more broadly for these services - they might be defined differently
echo "=== Looking for service definitions more broadly ==="
echo "Base compose file grep for all service keys:"
rg -n "^\s+[a-z_-]+:\s*$" pmoves/docker-compose.yml | head -50
echo ""
echo "=== Checking full line context for minio definition ==="
rg -B2 -A10 "^\s*minio:\s*$" pmoves/docker-compose.yml | head -40
echo ""
echo "=== Checking if prometheus, grafana, loki exist anywhere ==="
rg -i "prometheus|grafana|loki" pmoves/docker-compose.yml | head -20Repository: POWERFULMOVES/PMOVES.AI
Length of output: 2715
🏁 Script executed:
#!/bin/bash
# Look specifically for top-level services (two spaces, followed by service name, colon at end of line)
echo "=== All services defined in base compose ==="
rg -n "^ [a-z_-]+:\s*$" pmoves/docker-compose.yml
echo ""
echo "=== All services defined in VPS override ==="
rg -n "^ [a-z_-]+:\s*$" pmoves/docker-compose.vps.override.ymlRepository: POWERFULMOVES/PMOVES.AI
Length of output: 3919
🏁 Script executed:
#!/bin/bash
# Check if prometheus, grafana, loki are referenced as services anywhere or if they're part of pmoves_monitoring
echo "=== Checking pmoves_monitoring service definition ==="
rg -A30 "^\s+pmoves_monitoring:\s*$" pmoves/docker-compose.yml
echo ""
echo "=== Double-check: can we find prometheus, grafana, loki as service definitions? ==="
grep -n "^ prometheus:" pmoves/docker-compose.yml || echo "prometheus: NOT FOUND"
grep -n "^ grafana:" pmoves/docker-compose.yml || echo "grafana: NOT FOUND"
grep -n "^ loki:" pmoves/docker-compose.yml || echo "loki: NOT FOUND"
echo ""
echo "=== Check if these services are in VPS override ==="
grep -n "prometheus\|grafana\|loki" pmoves/docker-compose.vps.override.yml || echo "NONE FOUND"Repository: POWERFULMOVES/PMOVES.AI
Length of output: 1060
🏁 Script executed:
#!/bin/bash
# Let's look at the actual deployment script to confirm what's being deployed
echo "=== Viewing the deployment script file ==="
cat -n pbnj/pinokio/api/pmoves-pbnj/kvm4-2-deploy.json | head -20
echo ""
echo "=== Checking if neo4j is defined ==="
grep -n "^ neo4j:" pmoves/docker-compose.yml || echo "neo4j: NOT FOUND"Repository: POWERFULMOVES/PMOVES.AI
Length of output: 1381
Deployment command references non-existent services: prometheus, grafana, loki.
The deployment command on line 9 attempts to pull and start prometheus, grafana, and loki, but these services are not defined in either docker-compose.yml or docker-compose.vps.override.yml. The deployment will fail with a "service not found" error when docker-compose tries to reference these non-existent services. Additionally, the health check on line 11 expects Prometheus to be running at localhost:9090.
Either:
- Add service definitions for prometheus, grafana, and loki to the compose files, or
- Remove these services from the deployment command.
Confirm whether these observability services should be deployed on KVM4-2.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pbnj/pinokio/api/pmoves-pbnj/kvm4-2-deploy.json` at line 9, The deployment
command includes services "prometheus", "grafana", and "loki" in the ssh deploy
string and the health check expects Prometheus at localhost:9090, but those
services are not defined; either remove those service names from the ssh command
(the long ssh root@... '... docker compose -f docker-compose.yml -f
docker-compose.vps.override.yml pull ... && ... up -d ...' string) and
remove/adjust the Prometheus health check, or add proper service definitions for
prometheus, grafana, and loki into your docker-compose.yml and
docker-compose.vps.override.yml so the names match exactly; update the ssh
command to reference the newly-added services if you choose to add them.
| { text: "Cluster Status (AI Lab)", href: "status.json" }, | ||
|
|
||
| { text: "─── VPS Fleet ───", href: "" }, | ||
| { text: "Deploy KVM4-1 (API Gateway)", href: "kvm4-1-deploy.json" }, | ||
| { text: "Deploy KVM4-2 (Data Services)",href: "kvm4-2-deploy.json" }, | ||
| { text: "Deploy KVM2 (Exit Node)", href: "kvm2-deploy.json" }, | ||
| { text: "VPS Fleet Status", href: "vps-status.json" } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
find . -name pinokio.js -path "*/pmoves-pbnj/*" -type fRepository: POWERFULMOVES/PMOVES.AI
Length of output: 108
🏁 Script executed:
cat -n pbnj/pinokio/api/pmoves-pbnj/pinokio.js | head -50Repository: POWERFULMOVES/PMOVES.AI
Length of output: 1327
🏁 Script executed:
# Check the full file to understand menu structure
wc -l pbnj/pinokio/api/pmoves-pbnj/pinokio.jsRepository: POWERFULMOVES/PMOVES.AI
Length of output: 109
🏁 Script executed:
# Check if the referenced JSON files exist
ls -la pbnj/pinokio/api/pmoves-pbnj/*.json 2>/dev/null | head -20Repository: POWERFULMOVES/PMOVES.AI
Length of output: 1185
🏁 Script executed:
# Search for usage of info.exists, info.running, info.local in all pinokio.js files
rg "info\.(exists|running|local)" --type js -B2 -A2Repository: POWERFULMOVES/PMOVES.AI
Length of output: 2745
🏁 Script executed:
# Find all pinokio.js files to understand the pattern
fd pinokio.js -type fRepository: POWERFULMOVES/PMOVES.AI
Length of output: 237
🏁 Script executed:
# Fix the fd command to list all pinokio.js files
fd pinokio\.jsRepository: POWERFULMOVES/PMOVES.AI
Length of output: 246
🏁 Script executed:
# Get more context on the pattern - check if the async menu pattern is standard
grep -r "menu: async" --include="pinokio.js" | head -10Repository: POWERFULMOVES/PMOVES.AI
Length of output: 231
🏁 Script executed:
# Check the full structure of one of the example files to understand the pattern better
cat -n pmoves/docs/ARTSTUFF/realtime/pinokio.js | head -60Repository: POWERFULMOVES/PMOVES.AI
Length of output: 2142
🏁 Script executed:
# Verify if the pbnj file should also have async menu like the others
grep -A 5 "menu:" pbnj/pinokio/api/pmoves-pbnj/pinokio.jsRepository: POWERFULMOVES/PMOVES.AI
Length of output: 335
Convert the menu from a static array to an async function that uses Pinokio state functions to determine which items to display.
The entire menu is currently hardcoded as a static array, which exposes actions that may not be valid for the current state. Other pinokio.js files in this repository (e.g., pmoves/docs/ARTSTUFF/realtime/pinokio.js) use menu: async (kernel, info) => { ... } to dynamically generate menu items based on:
info.exists(relative_path)— whether a path existsinfo.running(relative_path)— whether a script is currently runninginfo.local(relative_path)— local variables from a running script
This pattern ensures the launcher only exposes valid actions for the current application state.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pbnj/pinokio/api/pmoves-pbnj/pinokio.js` around lines 17 - 23, Replace the
static menu array in pinokio.js with an async menu function: export menu: async
(kernel, info) => { ... } that builds and returns the menu list dynamically;
always include the "status.json" Cluster Status entry, then for each
deploy/status item ("kvm4-1-deploy.json", "kvm4-2-deploy.json",
"kvm2-deploy.json", "vps-status.json") call info.exists(relative_path) to decide
whether to include that item, use info.running(relative_path) to change text or
omit items when a script is running (e.g., show "Stop" vs "Deploy" or disable if
running), and consult info.local(relative_path) if you need per-script state to
further tailor labels; ensure the exported symbol is menu (async) and returns
the same shape as the original array so callers remain compatible.
| vps_fleet_manager: | ||
| name: "VPS Fleet Manager" | ||
| class: utility | ||
| primary_type: api | ||
| secondary_type: agent | ||
| port: null | ||
| health: null | ||
| layers: [L0, L2] | ||
| evolution_stage: base | ||
| nats: | ||
| publishes: ["mesh.vps.deploy.v1", "mesh.vps.status.v1"] | ||
| subscribes: ["mesh.vps.command.v1"] | ||
| chit_toggles: | ||
| delta_sensitive: false | ||
| kappa_sensitive: false | ||
| hz_sensitive: false | ||
| swarm_participant: false | ||
| attribution_gated: false | ||
| resilience: | ||
| context_budget: small | ||
| checkpoint_frequency: per_wave | ||
| recovery_strategy: manual_handoff | ||
| description: "Hostinger KVM fleet orchestration — deploy, status, restart via MCP tools" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify NATS subjects mesh.vps.* are referenced elsewhere in the codebase
echo "=== Searching for mesh.vps subject references ==="
rg -n --type yaml --type py --type js --type ts -C2 'mesh\.vps\.(deploy|status|command)'
echo ""
echo "=== Checking for VPS fleet deployment manifests ==="
fd -e yaml -e json 'vps' --exec head -20 {}Repository: POWERFULMOVES/PMOVES.AI
Length of output: 1535
🏁 Script executed:
#!/bin/bash
# Search for VPS-related service handlers, dispatchers, or integration code
echo "=== Searching for NATS message handlers or dispatchers ==="
rg -n 'handle.*mesh\.|dispatch.*mesh\.|subscribe.*mesh' --type py --type js --type ts -A3 | head -30
echo ""
echo "=== Checking for service handler patterns in codebase ==="
rg -n 'def.*handle\(|async.*handle\(|\.subscribe\(' --type py --type js --type ts pmoves/ 2>/dev/null | wc -l
echo ""
echo "=== Looking for any VPS or Hostinger references ==="
rg -i 'hostinger|vps|fleet.*manager' --type py --type md --type json | grep -v agent_registryRepository: POWERFULMOVES/PMOVES.AI
Length of output: 50383
🏁 Script executed:
#!/bin/bash
# Check cipher_categories presence in agent_registry.yaml
echo "=== Agents with resilience section and cipher_categories ==="
rg -B5 -A5 'cipher_categories' pmoves/config/agent_registry.yaml | head -40
echo ""
echo "=== Count of resilience sections with vs without cipher_categories ==="
echo "Resilience sections with cipher_categories:"
rg -c 'cipher_categories' pmoves/config/agent_registry.yaml
echo ""
echo "Total resilience sections:"
rg 'resilience:' pmoves/config/agent_registry.yaml | wc -l
echo ""
echo "=== Sample of agents WITH resilience (non-empty subset) ==="
rg -A8 'class: utility' pmoves/config/agent_registry.yaml | grep -A8 'resilience:' | head -30Repository: POWERFULMOVES/PMOVES.AI
Length of output: 1515
🏁 Script executed:
#!/bin/bash
# Check recovery_strategy patterns with cipher_categories
echo "=== Agents with manual_handoff recovery strategy ==="
rg -B10 'recovery_strategy: manual_handoff' pmoves/config/agent_registry.yaml | grep -E '(^\s+name:|recovery_strategy:|cipher_categories)' | head -20
echo ""
echo "=== Agents with cipher_resumable recovery strategy ==="
rg -B10 'recovery_strategy: cipher_resumable' pmoves/config/agent_registry.yaml | grep -E '(^\s+name:|recovery_strategy:|cipher_categories)' | head -20
echo ""
echo "=== Full botz_gateway resilience block ==="
rg -A10 'class: standard' pmoves/config/agent_registry.yaml | grep -A10 'botz_gateway' | head -20Repository: POWERFULMOVES/PMOVES.AI
Length of output: 507
🏁 Script executed:
#!/bin/bash
# More targeted search for resilience patterns
echo "=== Agents with manual_handoff (show full agent name and cipher_categories) ==="
rg -B15 'recovery_strategy: manual_handoff' pmoves/config/agent_registry.yaml | rg '^\s+[a-z_]+:|recovery_strategy|cipher_categories' | head -30
echo ""
echo "=== Checking if vps_fleet_manager is the only one without cipher_categories ==="
rg -A12 'class: utility|class: standard' pmoves/config/agent_registry.yaml | rg -E '(^\s+[a-z_]+:|resilience:)' -A12 | grep -B5 -A7 'recovery_strategy'Repository: POWERFULMOVES/PMOVES.AI
Length of output: 1512
🏁 Script executed:
#!/bin/bash
# Simpler approach: check which agents have resilience but NO cipher_categories
echo "=== Agents with resilience section ==="
rg -B5 'resilience:' pmoves/config/agent_registry.yaml | grep -E '^\s+[a-z_]+:$|resilience:' | head -30
echo ""
echo "=== Extract all agent names with their resilience/cipher_categories status ==="
python3 << 'PYTHON_EOF'
import yaml
with open('pmoves/config/agent_registry.yaml') as f:
agents = yaml.safe_load(f)['agents']
print("Agent Status (manual_handoff or no cipher_categories):")
print("-" * 70)
for name, config in agents.items():
if 'resilience' in config:
recovery = config['resilience'].get('recovery_strategy', 'N/A')
cipher = 'cipher_categories' in config['resilience']
if recovery == 'manual_handoff' or not cipher:
status = f"recovery={recovery}, has_cipher={cipher}"
print(f"{name:30} {status}")
PYTHON_EOFRepository: POWERFULMOVES/PMOVES.AI
Length of output: 688
Add cipher_categories to resilience section for consistency with recovery strategy pattern.
The vps_fleet_manager entry is well-structured and follows registry conventions. However, all agents using recovery_strategy: manual_handoff include a cipher_categories field—this agent should match that pattern:
♻️ Required consistency fix
resilience:
context_budget: small
checkpoint_frequency: per_wave
recovery_strategy: manual_handoff
+ cipher_categories: []The mesh.vps.* NATS subjects are correctly defined as an external infrastructure interface (deployed via Hostinger API and MCP tooling), consistent with how the gateway-agent abstracts infrastructure operations.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/config/agent_registry.yaml` around lines 687 - 709, The
vps_fleet_manager entry is missing the cipher_categories field under its
resilience block even though it uses recovery_strategy: manual_handoff; add a
cipher_categories key inside the resilience map for vps_fleet_manager and
populate it to match the same categories used by other agents with
manual_handoff (i.e., copy the exact cipher_categories value from an existing
manual_handoff agent) so the entry follows the established pattern.
| "production": { | ||
| "description": "Production deployment on kvm4 host", | ||
| "required_online": ["self-hosted,kvm4,production", "self-hosted,kvm4"], | ||
| "description": "Production deployment on KVM4 hosts with KVM2 backup", | ||
| "required_online": [ | ||
| "self-hosted,kvm4,production", | ||
| "self-hosted,kvm4" | ||
| ], | ||
| "optional_online": [ | ||
| "self-hosted,vps,kvm2" | ||
| ], | ||
| "required_offline": [], | ||
| "min_runners": 1 | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check lane_hosts.json for actual runner label definitions
echo "=== Checking lane_hosts.json for runner labels ==="
cat pmoves/integrations/github-runners/compose/lane_hosts.json 2>/dev/null | jq '.' || echo "File not found"Repository: POWERFULMOVES/PMOVES.AI
Length of output: 2929
🏁 Script executed:
cat pmoves/integrations/github-runners/compose/runner_phase_policy.jsonRepository: POWERFULMOVES/PMOVES.AI
Length of output: 1212
Inconsistent runner label patterns between deployment phases.
The vps-deployment phase uses labels like self-hosted,vps,kvm4-1, while the production phase uses self-hosted,kvm4,production and self-hosted,kvm4. Both patterns reference the same physical hosts (e.g., kvm4-1), but with different label schemes. Verify that runners are tagged with labels matching the required pattern for each phase, or standardize the label naming convention across phases.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/integrations/github-runners/compose/runner_phase_policy.json` around
lines 26 - 37, The production phase's required_online labels
("self-hosted,kvm4,production" and "self-hosted,kvm4") are inconsistent with the
vps-deployment naming (e.g., "self-hosted,vps,kvm4-1"); update the policy so
both phases use a single standardized label scheme or adjust the production
required_online/optional_online arrays to match the actual runner labels used
(for example change to "self-hosted,vps,kvm4-1" or remove the extra environment
token), and verify runner tag assignment so that the "production" phase's
min_runners logic and the "vps-deployment" phase resolve the same physical hosts
consistently.
- HOSTINGER_API_KEY → HOSTINGER_API_TOKEN (canonical per secrets_manifest_v2) - tensorzero → tensorzero-gateway in kvm4-1-deploy.json (match compose service name) - Remove kvm4 label from kvm4-2 runner (prevent cross-routing) - RG-3 manual checklist → make supa-collation-check (automated target) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Docker Hardening ValidationHardening Validation ReportValidated: Sun Mar 8 17:07:33 UTC 2026Services CheckedPMOVES.AI Docker Hardening Validation[INFO] Checking: pmoves/docker-compose.hardened.yml [INFO] Validating: hi-rag-gateway-v2 [INFO] Validating: extract-worker [INFO] Validating: langextract [INFO] Validating: presign [INFO] Validating: render-webhook [INFO] Validating: retrieval-eval [INFO] Validating: pdf-ingest [INFO] Validating: jellyfin-bridge [INFO] Validating: invidious-companion-proxy [INFO] Validating: ffmpeg-whisper [INFO] Validating: media-video [INFO] Validating: media-audio [INFO] Validating: hi-rag-gateway-v2-gpu [INFO] Validating: hi-rag-gateway-gpu [INFO] Validating: deepresearch [INFO] Validating: supaserch [INFO] Validating: publisher-discord [INFO] Validating: mesh-agent [INFO] Validating: nats-echo-req [INFO] Validating: nats-echo-res [INFO] Validating: publisher [INFO] Validating: analysis-echo [INFO] Validating: graph-linker [INFO] Validating: comfy-watcher [INFO] Validating: grayjay-plugin-host [INFO] Validating: agent-zero [INFO] Validating: archon [INFO] Validating: channel-monitor [INFO] Validating: pmoves-yt [INFO] Validating: notebook-sync [INFO] Validating: supabase_service_role_key [INFO] Validating: supabase_jwt_secret ====================================== |
CodeRabbit Review Response (commit 66d655b)Fixed
Dismissed — False Positive
Acknowledged — Out of Scope
|
- Makefile: supa-collation-refresh fails loudly on ALTER DATABASE errors - Makefile: supa-collation-check detects NULL/mismatched collation versions - deploy-vps: check_node() uses SSH probe, honors HOSTINGER_*_IP overrides - terraform: pin Hostinger provider to 0.1.22 - terraform/deploy: wire .env.vps into compose via --env-file - docs: filter 12 .venv false positives from tooling audit overlap table - docs: add VPS fleet workstream to production audit dashboard Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Test plan
git diff --stat mainconfirms expected file set🤖 Generated with Claude Code