docs: add Pinokio fleet networking TAC and packaging guides - #1115
Conversation
📝 WalkthroughWalkthroughAdded network inventory configuration defining three Pinokio LWW-enabled nodes with explicit service catalogs and security posture. Added four TAC tree task definitions covering defense-in-depth networking validation and per-node capability verification workflows. Added comprehensive Pinokio packaging documentation with manifest examples and testing/deployment guidance. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ 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.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7d3e771d07
ℹ️ 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".
| task: "Core infrastructure services healthy" | ||
| action: | ||
| type: shell | ||
| command: "docker compose -f pmoves/docker-compose.yml ps --format json | jq -r 'select(.Health==\"healthy\") | .Name'" |
There was a problem hiding this comment.
Iterate Compose JSON array before filtering healthy services
docker compose ps --format json emits a JSON array, but this jq filter treats the top-level value as an object; on real output it errors (Cannot index array with string "Health") instead of listing healthy containers. That makes this TAC check fail even when core services are healthy, so the health audit produces false negatives.
Useful? React with 👍 / 👎.
| expect: "No active serve proxies (empty output or error)" | ||
| context: > | ||
| tailscale serve masks broken networking by proxying through localhost. | ||
| Direct access must work: curl http://<tailscale-ip>:7860/gradio_api/info |
There was a problem hiding this comment.
Remove contradictory direct-IP curl expectation for Pinokio TTS
This step says direct curl http://<tailscale-ip>:7860/... must work, but the same networking TAC (and node-specific TACs) later document that direct IP:port access is expected to fail because Pinokio relies on HTTPS/SNI and LWW routing via port 42000. The contradiction makes operators misdiagnose healthy configurations as broken and follow the wrong remediation path.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 16
🤖 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/configs/pinokio-network-inventory.yaml`:
- Around line 27-97: The services list for hostname POWERFULMOVES is incomplete:
either add the missing intentional listeners referenced by the TAC (add service
entries for ffmpeg-whisper on port 8078, PMOVES.YT on port 8077, and the Pinokio
UI on port 42000 with appropriate class/owner/health_endpoint fields) or narrow
the file's claimed scope (remove or change the blanket LWW/exposed-services
claim such as pinokio_lww or the top-level comment) so it no longer asserts a
complete inventory; update the services block under the node with hostname
POWERFULMOVES accordingly to keep the inventory and TAC consistent.
In `@pmoves/configs/tac_trees/networking-defense-in-depth.tac.yaml`:
- Around line 85-94: Update the net.binding.no-tailscale-serve step so it does
not require raw http://<tailscale-ip>:7860 access: locate the block with id
"net.binding.no-tailscale-serve" (task "No tailscale serve workaround active")
and remove the raw Tailscale-IP curl example from the context and any
expectation that direct IP access must work; instead ensure the step only checks
the "tailscale serve status" output (or a host-name/SNI-aware access check if
needed) and adjust the "expect" and "context" strings to reflect that the check
verifies tailscale serve is inactive without asserting raw IP reachability.
- Around line 171-178: The task "net.docker.networks-exist" currently expects
all five networks to be internal; update it to reflect the actual compose
topology by checking that pmoves_data, pmoves_api, and pmoves_app are internal
while pmoves_bus is shared (not internal) and pmoves_monitoring's expected mode
as per compose; modify the "expect" text and the "pattern"/action so the
grep/assert verifies internal:true for pmoves_data|pmoves_api|pmoves_app and
that pmoves_bus is not internal (or explicitly marked shared) while leaving
pmoves_monitoring's requirement unchanged or set to its actual state; keep the
action type (grep) and target ("pmoves/docker-compose.yml") and only change the
expectation/pattern to match these exact network modes.
In `@pmoves/configs/tac_trees/node-5090-powerfulmoves.tac.yaml`:
- Around line 71-81: The task n5090.inventory.duplicate-removed uses type:
file_exists which passes when the directory is present—change it to an absence
check so it passes when the duplicate is removed: update the task's action to
use a "file_not_exists" (or the repo's equivalent absence verifier such as
"file_absent") instead of file_exists and keep or adjust the expect message to
something like "Directory removed" so the step succeeds when
D:/pinokio/api/vibevoice-realtime2.git is absent.
- Around line 269-277: The TAC entry id n5090.cross-machine.nats incorrectly
calls Z890 the hub; update the task, action.instruction, expect, and context to
reflect that 5090 is the NATS hub and Z890 is a leaf (per nats-leaf-z890.conf) —
e.g., change the task text to "NATS connectivity to Z890 leaf" or "NATS hub
(5090) connectivity", change the instruction to verify that Z890 (leaf)
successfully connects to the 5090 hub and that messages are routed via 5090,
adjust expect to "Bidirectional NATS messaging across Tailscale mesh via 5090
hub" and edit the context to state "5090 is the NATS hub; Z890 connects as a
leaf (see nats-leaf-z890.conf)". Ensure id n5090.cross-machine.nats remains if
still applicable.
In `@pmoves/configs/tac_trees/node-z890-coordinator.tac.yaml`:
- Around line 177-186: The check for id "nz890.tts-delegation.flute-bridge"
currently only hits Flute's /healthz; change the action so it validates Flute's
configured upstream (e.g., call an endpoint that reports the upstream/route or
perform a simple synthesis call) and assert the response contains the expected
upstream host/port "powerfulmoves-1.ts:7860" (or the ULTIMATE_TTS_URL value),
updating the action.url and action.expect fields accordingly so the test proves
routing to the 5090 Ultimate-TTS endpoint rather than just gateway health.
- Around line 90-122: The nz890.nats phase is contradictory: it declares Z890 as
the "primary NATS hub" (id: nz890.nats) but includes a child
nz890.nats.leaf-config checking pmoves/configs/nats-leaf-z890.conf which
describes Z890 as a leaf to 5090; pick one authoritative topology and make the
YAML consistent—either (A) keep Z890 as the hub: remove or rename the
leaf-config child (nz890.nats.leaf-config) and any reference to
pmoves/configs/nats-leaf-z890.conf, or update that file and the child to a
hub-focused config path and context, or (B) change nz890.nats' task/context to
indicate Z890 is a leaf and update nz890.nats.healthy and nz890.nats.jetstream
descriptions accordingly; ensure the chosen topology is reflected in id:
nz890.nats, the child nodes, and the referenced file name
pmoves/configs/nats-leaf-z890.conf.
In `@pmoves/docs/PINOKIO_EXAMPLE_MANIFESTS.md`:
- Around line 164-208: The .env.example written by the fs.write call
(params.path "app/.env.example") contains a YAML-like multiline block for
A0_MCP_SERVERS which is invalid dotenv syntax; replace that multiline structure
in the params.text with a single-line serialized value (e.g., JSON-encoded or
comma/semicolon-delimited string) for A0_MCP_SERVERS, or remove it from this
.env.example and add a note pointing to a separate JSON/YAML example file (e.g.,
mcp_servers.example.json) containing the structured MCP server definitions.
- Around line 621-634: The example manifest JSON uses unsupported gpu values
("recommended" and false) which break schema validation; update every manifest
example where the property "gpu" is present (e.g., the JSON object with "title":
"PMOVES Ultimate TTS Studio" and the other snippets noted) to use the documented
values ("required" or "optional") or omit the "gpu" field entirely per
guidelines, ensuring the field matches the schema used elsewhere in the PR.
- Around line 849-856: The shell.run steps in module.exports run use
params.path="../.." which from pbnj/pinokio/api/pmoves-services resolves to
pbnj/pinokio instead of the monorepo root containing pmoves/docker-compose.yml;
update the params.path value in those shell.run entries (identify by
method:"shell.run" and params.path) to point to the monorepo root (e.g.,
"../../../.." or the correct relative path from pbnj/pinokio/api/pmoves-services
to the repository root) and make the same change for the other occurrence around
lines 893-900 so the compose commands run in the directory containing
pmoves/docker-compose.yml.
- Around line 1191-1217: The manifest places the "returns" field inside params
so input.folder_path is never set; move the returns property out of params for
the first shell.run step (the object with method: "shell.run" that currently has
params:{ message: "pterm filepicker --directory", returns: "folder_path" }) so
it becomes a sibling to params (e.g., method: "shell.run", returns:
"folder_path", params:{ message: ... }); leave the subsequent steps referencing
input.folder_path unchanged so the value is properly populated for the "uv run"
shell.run and the notify step.
In `@pmoves/docs/PINOKIO_PACKAGING_GUIDE.md`:
- Around line 1077-1085: The pinokio.json example is not valid JSON because it
includes comments and ellipsis; update the example so it is parseable by
removing inline comments and the "..." and provide concrete placeholder values
for keys such as "version", "title", "engine", and "pmoves_version" (e.g., keep
"version": "1", "title": "PMOVES Agent Zero", "engine": "0.1.0",
"pmoves_version": "1.4.0") so the block is valid JSON and can pass the json.tool
check when copied into pinokio.json.
- Around line 318-340: The on.event regex in pinokio/start.js's run step for
method "shell.run" doesn't include a capture group, so local.set({ url:
input.event[1] }) gets undefined; update the "on.event" pattern to include a
capturing group around the URL (e.g., parentheses around the host:port or full
URL) so input.event[1] contains the captured URL, and ensure the shell.run
step's done flag is only set when that capturing regex matches; apply the same
fix to the other identical occurrence referenced in the doc (the second
"shell.run" / "local.set" sequence).
- Around line 1194-1248: The services catalog is out of sync: update
.claude/context/services-catalog.md to include the new entries and
port/health-endpoint details introduced in PINOKIO_PACKAGING_GUIDE.md (e.g.,
Agent Zero/pmoves-agent-zero port 8080, Archon/pmoves-archon 8091, Hi-RAG
v2/pmoves-hirag 8086/8087, SupaSerch/pmoves-supaserch 8099,
DeepResearch/pmoves-deepresearch 8098, TensorZero/pmoves-tensorzero 3030, Flute
Gateway/pmoves-flute 8055, PMOVES.YT/pmoves-yt 8077,
Ultimate-TTS/pmoves-ultimate-tts 7861, FFmpeg-Whisper/pmoves-whisper 8078,
Media-Video/pmoves-media-video 8079, Jellyfin Bridge/pmoves-jellyfin-bridge
8093, Cipher Memory/pmoves-cipher 8096, Crush/pmoves-crush,
EvoSwarm/pmoves-evoswarm 8113) and add the corresponding
GPU/required/recommended flags and health-check endpoints where applicable so
the shared catalog matches the appendix.
- Around line 345-359: The example reset.js uses a Unix-only shell command ("rm
-rf node_modules") which fails on Windows; update the launcher entry in
pinokio/reset.js so the "shell.run" params use a cross-platform approach (e.g.,
replace the raw rm command with a Node cross-platform command or a
platform-aware script invocation) and/or add a fallback that detects
process.platform and runs the appropriate command, and ensure the fs.rm entry
for "app/.env" remains intact; modify the "run" array entries (the shell.run
params.message and optionally add a new shell.run for Windows or a node script)
so the reset example works across Windows/WSL/Linux.
In `@pmoves/docs/PINOKIO_TESTING_DEPLOYMENT.md`:
- Around line 114-125: Update the example pterm invocations to point at the
actual script locations under the pinokio package directory rather than the
package root: change paths used in the pterm commands that reference install.js,
start.js and reset.js so they include the pinokio/ prefix (e.g., pterm start
/path/to/pmoves-agent-name/pinokio/install.js, pterm start .../pinokio/start.js,
pterm stop .../pinokio/start.js, and any reset.js usages). Apply this same
change to all similar blocks (the other occurrences noted) so the examples
reference pinokio/install.js, pinokio/start.js and pinokio/reset.js
consistently.
🪄 Autofix (Beta)
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
Run ID: 2cf16304-efa2-4d89-bdd3-578bad9f240e
📒 Files selected for processing (8)
pmoves/configs/pinokio-network-inventory.yamlpmoves/configs/tac_trees/networking-defense-in-depth.tac.yamlpmoves/configs/tac_trees/node-4090-laptop.tac.yamlpmoves/configs/tac_trees/node-5090-powerfulmoves.tac.yamlpmoves/configs/tac_trees/node-z890-coordinator.tac.yamlpmoves/docs/PINOKIO_EXAMPLE_MANIFESTS.mdpmoves/docs/PINOKIO_PACKAGING_GUIDE.mdpmoves/docs/PINOKIO_TESTING_DEPLOYMENT.md
| nodes: | ||
| - hostname: POWERFULMOVES | ||
| tailscale_host: powerfulmoves-1 | ||
| role: primary-gpu-tts | ||
| pinokio_lww: true | ||
| services: | ||
|
|
||
| # === PMOVES Intentional Services === | ||
| - name: Ultimate-TTS-Studio | ||
| port: 7860 | ||
| class: intentional | ||
| owner: pinokio | ||
| description: "14-engine TTS hub (Gradio)" | ||
| health_endpoint: "/gradio_api/info" | ||
|
|
||
| - name: Qwen3-TTS | ||
| port: dynamic | ||
| class: intentional | ||
| owner: pinokio | ||
| description: "Qwen3 standalone TTS with VoiceDesign mode" | ||
| health_endpoint: "/gradio_api/info" | ||
|
|
||
| - name: VibeVoice-Realtime | ||
| port: dynamic | ||
| class: intentional | ||
| owner: pinokio | ||
| description: "WebSocket streaming TTS (uvicorn)" | ||
| health_endpoint: null | ||
|
|
||
| - name: VoxForge-Pro | ||
| port: dynamic | ||
| class: intentional | ||
| owner: pinokio | ||
| description: "PDF-to-audiobook pipeline" | ||
| health_endpoint: "/gradio_api/info" | ||
|
|
||
| - name: Ollama | ||
| port: 11434 | ||
| class: intentional | ||
| owner: docker | ||
| description: "Local LLM inference" | ||
| health_endpoint: "/api/tags" | ||
|
|
||
| - name: N8N | ||
| port: dynamic | ||
| class: intentional | ||
| owner: pinokio | ||
| description: "Workflow automation" | ||
| health_endpoint: "/healthz" | ||
|
|
||
| - name: SillyTavern | ||
| port: dynamic | ||
| class: intentional | ||
| owner: pinokio | ||
| description: "Chat interface for LLMs" | ||
| health_endpoint: null | ||
|
|
||
| - name: ACE-Step | ||
| port: dynamic | ||
| class: intentional | ||
| owner: pinokio | ||
| description: "Music generation" | ||
| health_endpoint: null | ||
|
|
||
| - name: WAN | ||
| port: dynamic | ||
| class: intentional | ||
| owner: pinokio | ||
| description: "Video generation" | ||
| health_endpoint: null | ||
|
|
There was a problem hiding this comment.
Complete the 5090 inventory or narrow this file's scope.
This file says it classifies all LWW-exposed services, but the companion TAC at pmoves/configs/tac_trees/node-5090-powerfulmoves.tac.yaml also audits ffmpeg-whisper on :8078, PMOVES.YT on :8077, and the fleet relies on the 5090 Pinokio UI on :42000. None of those intentional listeners appear here, so the "inventory vs noise" audit cannot use this as a source of truth yet.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/configs/pinokio-network-inventory.yaml` around lines 27 - 97, The
services list for hostname POWERFULMOVES is incomplete: either add the missing
intentional listeners referenced by the TAC (add service entries for
ffmpeg-whisper on port 8078, PMOVES.YT on port 8077, and the Pinokio UI on port
42000 with appropriate class/owner/health_endpoint fields) or narrow the file's
claimed scope (remove or change the blanket LWW/exposed-services claim such as
pinokio_lww or the top-level comment) so it no longer asserts a complete
inventory; update the services block under the node with hostname POWERFULMOVES
accordingly to keep the inventory and TAC consistent.
| - id: net.binding.no-tailscale-serve | ||
| task: "No tailscale serve workaround active" | ||
| action: | ||
| type: shell | ||
| command: "tailscale serve status" | ||
| expect: "No active serve proxies (empty output or error)" | ||
| context: > | ||
| tailscale serve masks broken networking by proxying through localhost. | ||
| Direct access must work: curl http://<tailscale-ip>:7860/gradio_api/info | ||
| agent_hint: codex |
There was a problem hiding this comment.
Remove the raw Tailscale-IP requirement from the no-serve check.
This step says raw http://<tailscale-ip>:7860 must work, but later in the same TAC the LWW section correctly says direct app-port access fails because Pinokio's Caddy proxy needs TLS SNI/hostname routing. Keeping both expectations will make the audit fail the intended path.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/configs/tac_trees/networking-defense-in-depth.tac.yaml` around lines
85 - 94, Update the net.binding.no-tailscale-serve step so it does not require
raw http://<tailscale-ip>:7860 access: locate the block with id
"net.binding.no-tailscale-serve" (task "No tailscale serve workaround active")
and remove the raw Tailscale-IP curl example from the context and any
expectation that direct IP access must work; instead ensure the step only checks
the "tailscale serve status" output (or a host-name/SNI-aware access check if
needed) and adjust the "expect" and "context" strings to reflect that the check
verifies tailscale serve is inactive without asserting raw IP reachability.
| - id: net.docker.networks-exist | ||
| task: "All 5 internal networks defined with correct CIDRs" | ||
| action: | ||
| type: grep | ||
| target: "pmoves/docker-compose.yml" | ||
| pattern: "pmoves_(data|api|app|bus|monitoring)" | ||
| expect: "5 networks: pmoves_data, pmoves_api, pmoves_app, pmoves_bus, pmoves_monitoring" | ||
| context: "Each network uses internal: true with CIDR blocks 172.30.x.0/24" |
There was a problem hiding this comment.
Audit the actual internal/shared network mix from compose.
pmoves/docker-compose.yml marks pmoves_data, pmoves_api, and pmoves_app as internal, but pmoves_bus is deliberately shared. Requiring all five networks to be internal will flag the current compose topology as broken when it is not.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/configs/tac_trees/networking-defense-in-depth.tac.yaml` around lines
171 - 178, The task "net.docker.networks-exist" currently expects all five
networks to be internal; update it to reflect the actual compose topology by
checking that pmoves_data, pmoves_api, and pmoves_app are internal while
pmoves_bus is shared (not internal) and pmoves_monitoring's expected mode as per
compose; modify the "expect" text and the "pattern"/action so the grep/assert
verifies internal:true for pmoves_data|pmoves_api|pmoves_app and that pmoves_bus
is not internal (or explicitly marked shared) while leaving pmoves_monitoring's
requirement unchanged or set to its actual state; keep the action type (grep)
and target ("pmoves/docker-compose.yml") and only change the expectation/pattern
to match these exact network modes.
| - id: n5090.inventory.duplicate-removed | ||
| task: "vibevoice-realtime2.git removed (duplicate)" | ||
| action: | ||
| type: file_exists | ||
| target: "D:/pinokio/api/vibevoice-realtime2.git" | ||
| expect: "Directory removed — saves ~2-3 GB disk and eliminates confusion" | ||
| context: > | ||
| vibevoice-realtime2 is an exact duplicate of vibevoice-realtime with | ||
| only a pinokio.json version difference. No unique features. | ||
| agent_hint: 5090-claude | ||
| status: pending |
There was a problem hiding this comment.
Use an absence check for the duplicate-removal task.
type: file_exists paired with expect: "Directory removed" verifies the opposite condition: this step only succeeds when vibevoice-realtime2.git is still present.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/configs/tac_trees/node-5090-powerfulmoves.tac.yaml` around lines 71 -
81, The task n5090.inventory.duplicate-removed uses type: file_exists which
passes when the directory is present—change it to an absence check so it passes
when the duplicate is removed: update the task's action to use a
"file_not_exists" (or the repo's equivalent absence verifier such as
"file_absent") instead of file_exists and keep or adjust the expect message to
something like "Directory removed" so the step succeeds when
D:/pinokio/api/vibevoice-realtime2.git is absent.
| - id: n5090.cross-machine.nats | ||
| task: "NATS connectivity to Z890 hub" | ||
| action: | ||
| type: manual | ||
| instruction: "Verify NATS messages from Z890 are received on 5090" | ||
| expect: "Bidirectional NATS messaging across Tailscale mesh" | ||
| context: > | ||
| Z890 runs the NATS hub. 5090 connects as leaf node or direct client. | ||
| Cross-ref: networking-defense-in-depth.tac.yaml → net.nats-leaf |
There was a problem hiding this comment.
Point the 5090 TAC at the actual NATS hub.
pmoves/configs/nats-leaf-z890.conf defines Z890 as the leaf that connects upstream to the 5090 hub, so auditing "connectivity to Z890 hub" inverts the topology and sends incident triage to the wrong node.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/configs/tac_trees/node-5090-powerfulmoves.tac.yaml` around lines 269 -
277, The TAC entry id n5090.cross-machine.nats incorrectly calls Z890 the hub;
update the task, action.instruction, expect, and context to reflect that 5090 is
the NATS hub and Z890 is a leaf (per nats-leaf-z890.conf) — e.g., change the
task text to "NATS connectivity to Z890 leaf" or "NATS hub (5090) connectivity",
change the instruction to verify that Z890 (leaf) successfully connects to the
5090 hub and that messages are routed via 5090, adjust expect to "Bidirectional
NATS messaging across Tailscale mesh via 5090 hub" and edit the context to state
"5090 is the NATS hub; Z890 connects as a leaf (see nats-leaf-z890.conf)".
Ensure id n5090.cross-machine.nats remains if still applicable.
| ```javascript | ||
| // pinokio/start.js | ||
| module.exports = { | ||
| run: [ | ||
| { | ||
| method: "shell.run", | ||
| params: { | ||
| path: "app", | ||
| message: "npm start", | ||
| on: [{ | ||
| event: "/http://localhost:[0-9]+/", | ||
| done: true | ||
| }] | ||
| } | ||
| }, | ||
| { | ||
| method: "local.set", | ||
| params: { | ||
| url: input.event[1] // Captured URL from regex | ||
| } | ||
| } | ||
| ] | ||
| } |
There was a problem hiding this comment.
Add capture groups before reading input.event[1].
Neither regex captures the URL, so local.set({ url: input.event[1] }) stores undefined and the generated "Open" links break.
Suggested doc fix
- on: [{
- event: "/http://localhost:[0-9]+/",
+ on: [{
+ event: "/(http:\\/\\/localhost:[0-9]+)/",
done: true
}]
...
- on: [{
- event: "/Uvicorn running on/",
+ on: [{
+ event: "/Uvicorn running on (http:\\/\\/[0-9.:]+)/",
done: true
}]Also applies to: 496-518
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/docs/PINOKIO_PACKAGING_GUIDE.md` around lines 318 - 340, The on.event
regex in pinokio/start.js's run step for method "shell.run" doesn't include a
capture group, so local.set({ url: input.event[1] }) gets undefined; update the
"on.event" pattern to include a capturing group around the URL (e.g.,
parentheses around the host:port or full URL) so input.event[1] contains the
captured URL, and ensure the shell.run step's done flag is only set when that
capturing regex matches; apply the same fix to the other identical occurrence
referenced in the doc (the second "shell.run" / "local.set" sequence).
| ```javascript | ||
| // pinokio/reset.js | ||
| module.exports = { | ||
| run: [ | ||
| { | ||
| method: "shell.run", | ||
| params: { | ||
| path: "app", | ||
| message: "rm -rf node_modules" | ||
| } | ||
| }, | ||
| { | ||
| method: "fs.rm", | ||
| params: { path: "app/.env" } | ||
| } |
There was a problem hiding this comment.
Make the canonical reset.js example cross-platform.
rm -rf node_modules is Unix-only, so the main cleanup example here breaks on Windows even though the guide presents these launchers as cross-platform.
Suggested doc fix
- {
- method: "shell.run",
- params: {
- path: "app",
- message: "rm -rf node_modules"
- }
- },
+ {
+ method: "fs.rm",
+ params: { path: "app/node_modules" }
+ },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/docs/PINOKIO_PACKAGING_GUIDE.md` around lines 345 - 359, The example
reset.js uses a Unix-only shell command ("rm -rf node_modules") which fails on
Windows; update the launcher entry in pinokio/reset.js so the "shell.run" params
use a cross-platform approach (e.g., replace the raw rm command with a Node
cross-platform command or a platform-aware script invocation) and/or add a
fallback that detects process.platform and runs the appropriate command, and
ensure the fs.rm entry for "app/.env" remains intact; modify the "run" array
entries (the shell.run params.message and optionally add a new shell.run for
Windows or a node script) so the reset example works across Windows/WSL/Linux.
| ```json | ||
| // pinokio.json with versioning | ||
| { | ||
| "version": "1", | ||
| "title": "PMOVES Agent Zero", | ||
| "engine": "0.1.0", // Minimum Pinokio version | ||
| "pmoves_version": "1.4.0", // PMOVES taxonomy version | ||
| ... | ||
| } |
There was a problem hiding this comment.
Keep pinokio.json examples parseable.
This json block contains comments and ..., so it is not valid JSON. Readers who copy it into pinokio.json will fail the json.tool check described earlier in this document.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/docs/PINOKIO_PACKAGING_GUIDE.md` around lines 1077 - 1085, The
pinokio.json example is not valid JSON because it includes comments and
ellipsis; update the example so it is parseable by removing inline comments and
the "..." and provide concrete placeholder values for keys such as "version",
"title", "engine", and "pmoves_version" (e.g., keep "version": "1", "title":
"PMOVES Agent Zero", "engine": "0.1.0", "pmoves_version": "1.4.0") so the block
is valid JSON and can pass the json.tool check when copied into pinokio.json.
| | Agent | Class | Tier | Port | GPU | Pinokio Package | | ||
| |-------|-------|------|------|-----|-----------------| | ||
| | Agent Zero | Standard | 6+2 | 8080 | Optional | `pmoves-agent-zero` | | ||
| | Archon | Standard | 6+3 | 8091 | Optional | `pmoves-archon` | | ||
| | Hi-RAG v2 | Standard | 4+1 | 8086/8087 | Optional | `pmoves-hirag` | | ||
| | SupaSerch | Standard | 6+3 | 8099 | Optional | `pmoves-supaserch` | | ||
| | DeepResearch | Standard | 3+4 | 8098 | Optional | `pmoves-deepresearch` | | ||
| | TensorZero | Standard | 2+3 | 3030 | No | `pmoves-tensorzero` | | ||
| | Flute Gateway | Standard | 2+5 | 8055 | Optional | `pmoves-flute` | | ||
| | PMOVES.YT | Standard | 5+4 | 8077 | Optional | `pmoves-yt` | | ||
| | Ultimate-TTS | Standard | 5+3 | 7861 | Recommended | `pmoves-ultimate-tts` | | ||
| | FFmpeg-Whisper | Standard | 5+4 | 8078 | Recommended | `pmoves-whisper` | | ||
| | Media-Video | Standard | 5+4 | 8079 | Required | `pmoves-media-video` | | ||
| | Jellyfin Bridge | Specialized | 5+1 | 8093 | No | `pmoves-jellyfin-bridge` | | ||
| | Cipher Memory | Specialized | 1+6 | 8096 | No | `pmoves-cipher` | | ||
| | Crush | Standard | 7+6 | - | No | `pmoves-crush` | | ||
| | EvoSwarm | Standard | 4+6 | 8113 | Required | `pmoves-evoswarm` | | ||
|
|
||
| --- | ||
|
|
||
| ## Appendix B: Environment Variables Reference | ||
|
|
||
| ### Common PMOVES Environment Variables | ||
|
|
||
| ```bash | ||
| # Supabase (required for most agents) | ||
| SUPABASE_URL=https://xxx.supabase.co | ||
| SUPABASE_SERVICE_ROLE_KEY=xxx | ||
|
|
||
| # NATS (event bus) | ||
| NATS_URL=nats://localhost:4222 | ||
|
|
||
| # LLM Providers (at least one required) | ||
| OPENAI_API_KEY=xxx | ||
| ANTHROPIC_API_KEY=xxx | ||
| GOOGLE_API_KEY=xxx | ||
|
|
||
| # Vector DBs | ||
| QDRANT_URL=http://localhost:6333 | ||
| NEO4J_URI=bolt://localhost:7687 | ||
| NEO4J_USER=neo4j | ||
| NEO4J_PASSWORD=xxx | ||
|
|
||
| # Search | ||
| MEILISEARCH_URL=http://localhost:7700 | ||
| MEILISEARCH_KEY=xxx | ||
|
|
||
| # Storage (Supabase Storage S3) | ||
| MINIO_ENDPOINT=http://localhost:65421/storage/v1/s3 | ||
| MINIO_ACCESS_KEY=xxx | ||
| MINIO_SECRET_KEY=xxx | ||
|
|
||
| # GPU | ||
| CUDA_VISIBLE_DEVICES=0 | ||
| ``` |
There was a problem hiding this comment.
Sync the shared services catalog with this appendix.
This appendix adds concrete service ports and health-relevant endpoints, but .claude/context/services-catalog.md is not updated in the PR. That leaves the shared ops catalog out of sync with the new Pinokio docs and TACs.
As per coding guidelines, "maintain services catalog with port assignments and health endpoints in .claude/context/services-catalog.md".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/docs/PINOKIO_PACKAGING_GUIDE.md` around lines 1194 - 1248, The
services catalog is out of sync: update .claude/context/services-catalog.md to
include the new entries and port/health-endpoint details introduced in
PINOKIO_PACKAGING_GUIDE.md (e.g., Agent Zero/pmoves-agent-zero port 8080,
Archon/pmoves-archon 8091, Hi-RAG v2/pmoves-hirag 8086/8087,
SupaSerch/pmoves-supaserch 8099, DeepResearch/pmoves-deepresearch 8098,
TensorZero/pmoves-tensorzero 3030, Flute Gateway/pmoves-flute 8055,
PMOVES.YT/pmoves-yt 8077, Ultimate-TTS/pmoves-ultimate-tts 7861,
FFmpeg-Whisper/pmoves-whisper 8078, Media-Video/pmoves-media-video 8079,
Jellyfin Bridge/pmoves-jellyfin-bridge 8093, Cipher Memory/pmoves-cipher 8096,
Crush/pmoves-crush, EvoSwarm/pmoves-evoswarm 8113) and add the corresponding
GPU/required/recommended flags and health-check endpoints where applicable so
the shared catalog matches the appendix.
| ```bash | ||
| # Test install script | ||
| pterm start /path/to/pmoves-agent-name/install.js | ||
|
|
||
| # Test start script | ||
| pterm start /path/to/pmoves-agent-name/start.js | ||
|
|
||
| # View logs | ||
| pterm logs /path/to/pmoves-agent-name | ||
|
|
||
| # Stop running script | ||
| pterm stop /path/to/pmoves-agent-name/start.js |
There was a problem hiding this comment.
Fix the pterm script paths.
These examples call install.js, start.js, and reset.js from the package root even though the layout above puts those files under pinokio/. Anyone following the smoke steps here will hit missing-file errors before they reach the launcher scripts.
Suggested doc fix
- pterm start /path/to/pmoves-agent-name/install.js
- pterm start /path/to/pmoves-agent-name/start.js
- pterm stop /path/to/pmoves-agent-name/start.js
- pterm start /path/to/pmoves-agent-name/reset.js
+ pterm start /path/to/pmoves-agent-name/pinokio/install.js
+ pterm start /path/to/pmoves-agent-name/pinokio/start.js
+ pterm stop /path/to/pmoves-agent-name/pinokio/start.js
+ pterm start /path/to/pmoves-agent-name/pinokio/reset.jsAlso applies to: 191-201, 212-221, 246-255, 553-559, 760-768
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pmoves/docs/PINOKIO_TESTING_DEPLOYMENT.md` around lines 114 - 125, Update the
example pterm invocations to point at the actual script locations under the
pinokio package directory rather than the package root: change paths used in the
pterm commands that reference install.js, start.js and reset.js so they include
the pinokio/ prefix (e.g., pterm start
/path/to/pmoves-agent-name/pinokio/install.js, pterm start .../pinokio/start.js,
pterm stop .../pinokio/start.js, and any reset.js usages). Apply this same
change to all similar blocks (the other occurrences noted) so the examples
reference pinokio/install.js, pinokio/start.js and pinokio/reset.js
consistently.
…ity hardening Fleet Networking & RustDesk: - KVM2 self-hosted RustDesk relay (hbbs+hbbr, systemd, UFW-locked) - Scripts: fix-kvm2-rustdesk-relay.sh, restart-jetson-rustdesk.sh (env var driven — HOSTINGER_KVM2_IP, RUSTDESK_RELAY_KEY, JETSON_IPS) - RUSTDESK_SELF_HOSTED.md deployment guide (sanitized, no secrets) - QR code generation instructions for mobile enrollment Security Hardening: - Network hardening: localhost defaults for all service bindings - 4090 laptop host hardening script - SSH key-only auth across 8 nodes (password disabled) - Gitignore: rustdesk QR images excluded from repo Infrastructure: - DeepResearch Dockerfile: add pmoves.chit COPY for CGP_SPEC_VERSION (Python files only, secrets manifests excluded from image layers) - TOPOLOGY.md: KVM2 RustDesk ports, updated node hostnames, Jetson status - AGNOTE4482 ACK: Z890-CLAUDE fleet networking claim signed Also includes merged PR content: - Hi-RAG embedding defaults aligned to Qwen3 2560d (#1122) - Pinokio Codex plugin + Agent Zero launcher (#1121) - Publishing approval handoff state (#1120) - TTS MCP bridge + expression registry (#1116) - Damage-control hooks Windows compat (#1123) - AGNOTE4482 fleet claim docs (#1127) - Dependency bumps (#1111, #1113, #1128) - Bootstrap SUPERSEDED_VALUES (#1112) - Various docs updates (#1115, #1117, #1119, #1124, #1125) - Publisher RPC idempotent guards (#1126) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
docs: add Pinokio fleet networking TAC and packaging guides
Summary
Validation
Notes
Summary by CodeRabbit
New Features
Documentation