Skip to content

feat(pi-coding-agent): add agent kit that renders provider input into pi - #1

Merged
mogul merged 12 commits into
mainfrom
add-pi-coding-agent-kit
Oct 27, 2026
Merged

mogul merged 12 commits into
mainfrom
add-pi-coding-agent-kit

Conversation

@mogul

@mogul mogul commented Oct 26, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a pi-coding-agent agent kit alongside opencode-go-provider. It installs the Pi coding agent (@earendil-works/pi-coding-agent) inside the sandbox and renders acq's host-materialized provider generation into Pi's ~/.pi/agent/models.json, so pi --list-models lists every model the selected provider kit publishes.

What's included

  • spec.yaml — hybrid/v1 mixin; install host only (registry.npmjs.org); two startup commands (install → render); no agent: block; no published ports.
  • files/home/pi-coding-agent-install.sh — fresh npm install (pinned 1.4.0, --ignore-scripts, per-user prefix, idempotent, fail-soft, CA-bundle wrapper).
  • files/home/pi-coding-agent-render-models.mjs — fail-closed renderer: reads $ACQ_PROVIDER_INPUT_ROOT/models/providers/*/{facts.json,snapshot.json}, maps the neutral vocabulary → Pi models.json (openai-compatible → openai-completions, keyEnv → $KEY_ENV + authHeader, maxOutputTokens → maxTokens, cost fields defaulted), atomic write.
  • tests/ — 25 node:test cases + vendored acq schemas + opencode-go fixtures.
  • scripts/verify — offline gate + RUN_ACQ=1 live gate (create a sandbox with both kits, assert pi on PATH and pi --list-models lists the provider models).
  • README.md, TROUBLESHOOTING.md, docs/decisions/ (install method, renderer mapping).

Review

Passed an adversarial review that fixed 16 substantive findings (prototype-key protocol bypass, regex $ trailing-newline bypasses, symlink-following of provider inputs, wrapper shell injection via a hostile $HOME, half-install idempotency, and more).

Verification

Dependencies

AI-assisted (OpenCode). Human review required.

mogul added 12 commits October 26, 2026 02:13
Install pi from npm at a reviewed 1.4.0 pin, unprivileged into ~/.local with --ignore-scripts, idempotent and fail-soft. Render acq's host-materialized provider generation into ~/.pi/agent/models.json with fail-closed validation of facts, catalog, provider identity, host agreement, and protocol. Map the neutral vocabulary to pi's openai-completions provider shape, including all four cost fields and 200k pricing tiers. Add node:test coverage, vendored neutral schemas, an opencode-go fixture, and an offline/live verify script. Update the repository README and CI for provider and agent kits.
…ystem edge cases

Accept empty model catalogs, validate every emitted shape against a vendored copy of the live pi.dev models schema, and mirror the neutral schemas' full-match patterns, length limits, control-character rules, and field allowlists. Reject symlinked provider directories and input files, replace (not follow) a symlinked models.json target, and use code-unit ordering for deterministic output. Expand the node:test suite across empty catalogs, absent/partial/full/tiered costs, duplicate providers, the 500-model limit, recommendations, trailing newlines, control characters, URL/host edge cases, and symlink attacks.
…otent

Replace path interpolation in the generated pi wrapper with a sibling pi-real entrypoint resolved from \, eliminating shell-injection risk from a hostile HOME. Verify pi --version before taking the idempotent path so a half-finished install is repaired, honor an existing working pi, add --no-audit/--no-fund, and move the fail-soft trap into a shellcheck-clean function. Extend scripts/verify with shellcheck, stub-npm boot/recovery/failure tests, hostile-HOME and newline-HOME injection tests, CA-decode checks, and arithmetic tests for the Node >=22.19.0 gate.
…n CI

Document the pi-real wrapper, pre-existing-pi behavior, tiered-cost semantics, schema full-match validation, symlink rejection, and the expanded verify gates. Add the built-in provider-id merge caveat to agentContext. Validate spec.yaml against a vendored copy of the patterns kit schema in npm test, and add a guarded patterns-validator CI step for checkouts that contain it.
Use a null-prototype protocol adapter table so __proto__, constructor, and toString cannot resolve truthy values from Object.prototype and bypass unsupported-apiProtocol rejection. Match the neutral schema's unbounded integer type with Number.isInteger instead of rejecting schema-valid large context windows. Add regression cases for prototype-key protocols and keep the full renderer suite green.
…vior

State that pi's request-wide tier is the closest representation of the neutral context-window tier, and that a pre-existing pi outside the kit prefix is honored but does not inherit the kit's CA wrapper.
Assert that a model object carrying a field outside the neutral schema fails closed, matching the existing facts, catalog, and cost checks.
Fall back to the documented provider root and agent config directory when ACQ_PROVIDER_INPUT_ROOT, PI_CODING_AGENT_DIR, or HOME is set to an empty string, instead of resolving a relative models/providers path or writing models.json into the current directory.
Lock in authoritative-empty behavior for an existing empty providers directory, fail-closed behavior for a missing snapshot, and rejection of a non-object recommendations block.
Describe recovery as happening in the same boot, and clarify that the wrapper is written on the first successful install and left alone thereafter.
…entry

Use the acq-kits-registry schema/backends/parity shape in the temporary registry used by the guarded patterns validation step, so a validator checkout that validates registry structure accepts it.
Explain that the neutral facts do not carry provider-specific request headers, and that pi's extra bundled ids for a colliding provider id may not be served by the mapped protocol; the provider kit's catalog is the supported set.
@mogul
mogul merged commit b212e39 into main Oct 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant