SolidForge for the Pi coding agent — an independent, pi-native implementation of the SolidForge Loop Engineering system: the converge → specify → implement pipeline plus two additive outcome-axis layers (cited-source verification + uncited prior-art collision). Design lineage: solidforge (the Claude Code reference implementation) — its ADRs remain the shared design authority and knowledge flows both ways, but there is no git upstream/sync relationship; code sharing is narrow, deliberate, and ledgered in docs/upstream-watch.md.
- Skills (5) —
cross-source-review,blueprint-crafting,parallel-development,primary-source-verification,prior-art-search(invoke/skill:solidforge:<name>or the bare/solidforge:<name>on a pi.namespace-capable pi;/skill:<name>on stock pi) - Agents (22) — plugin-scoped as
solidforge:<name>, dispatched via the bundledsubagenttool (isolated context; single / parallel / chain) - Guards — the convergence-loop hooks (
blueprint_guard/counters/fast_gate) bridged to pi'stool_call/tool_resultevents by thesf-hooksextension - Heterogeneous (异源) review substrate — the different-family review legs spawn stateless
pi --mode jsonsubprocesses on provider routes different from the orchestrator's family, with wrapper-side budget/turn/bytes/wall-clock breakers (ADR #41/#43/#52 semantics preserved)
pi install git:github.com/maskshell/solidforge-pi # or: pi install ./solidforge-piRequires python3 on $PATH (all gate/policy scripts are Python stdlib-only CLIs). Release gate: python3 tools/pi_loader_smoke.py asserts the package loads under pi's REAL resource loaders (exact 5-skill set, zero diagnostics, manifest paths resolve) — the cross-harness frontmatter regression class per-skill gates cannot see.
Optional prerequisite — pi-mcp-adapter, only for the Playwright E2E trio and Graphiti memory:
pi install npm:pi-mcp-adapter
# then configure the playwright-test server, e.g. in .mcp.json:
# { "mcpServers": { "playwright-test": { "command": "npx", "args": ["-y", "@playwright/test-mcp"] } } }Without the adapter, the playwright agents fall back to the Playwright CLI (npx playwright codegen|test), and Graphiti memory ops degrade gracefully (the skill skips them).
Enabling the package does NOT mutate host-project build files. In a target project run:
/solidforge:arm-tools # pi.namespace-capable pi — provision arch-configs + constitution + templates
/solidforge:arm-tools --with-tools # …also add version-matched gate tools to dev deps
/arm-tools # stock-pi fallback (no namespace: template name = filename)
The namespace form requires a pi build with pi.namespace support (this package declares "namespace": "solidforge"; see the proposal + implementation at maskshell/pi, branch package-namespace, tracked in earendil-works/pi#8834).
arm.py appends the L1 Constitution to the project's AGENTS.md (when present) or CLAUDE.md — pi loads either. Reversible: arm.py --revert (dry-run; --apply to execute).
Profiles are pi catalog routes (model facts catalog-inherited; the CC-era [1M] suffix is a context-window parameter and never appears in a pi model id):
| profile (alias) | route | model | credential |
|---|---|---|---|
zai-coding-cn (bigmodel) |
zai-coding-cn — GLM coding endpoint, openai-completions | glm-5.3 |
pi auth.json (default provider) or ZAI_CODING_CN_API_KEY |
deepseek |
deepseek — native endpoint | deepseek-v4-flash |
DEEPSEEK_API_KEY ← bridged from DEEPSEEK_ANTHROPIC_AUTH_TOKEN |
minimax-cn (minimax) |
minimax-cn — anthropic endpoint | MiniMax-M3 |
MINIMAX_CN_API_KEY ← bridged from MINIMAX_ANTHROPIC_AUTH_TOKEN |
qwen-bailian (qwen3) |
custom route (pi catalog has only token-plan subscription qwen routes; Bailian pay-per-use key registered by sf-providers when present) |
qwen3.8-max |
QWEN3_ANTHROPIC_AUTH_TOKEN (the DashScope pay-per-use key) |
qwen-token-plan-cn |
qwen-token-plan-cn — token-plan subscription | qwen3.8-max |
QWEN_TOKEN_PLAN_CN_API_KEY |
Put tokens in the target project's .env.solidforge (shell env wins; arm-tools provisions the .env.solidforge.example placeholder). Select legs via HETERO_DOC_PROFILE / HETERO_PROFILE (comma-list = multi-different-family). CC-era profile names (bigmodel, minimax, qwen3) keep working via aliases.
Budget/cost note: routes with catalog pricing (deepseek, minimax-cn) feed real usage.cost.total into the wrapper-side budget breaker; zai-coding-cn and qwen-bailian report cost 0 (unknown to the catalog) — the budget cap is inert there, wall-clock/turns/bytes caps still apply.
The subagent tool and the hetero wrappers spawn pi --mode json -p children. Non-interactive runs do not show the project-trust prompt: without a saved trust decision they follow defaultProjectTrust (ask default = project-local .pi resources ignored). For CI, either save a trust decision interactively first (/trust) or set defaultProjectTrust: "always" in ~/.pi/agent/settings.json (weigh the security tradeoff), or pass --approve.
solidforge-pi/
├── package.json # pi manifest (pi.extensions / pi.skills / pi.prompts)
├── skills/ # 5 skills (SKILL.md + stdlib python infra + self-gates)
├── prompts/arm-tools.md # /solidforge:arm-tools via pi.namespace
├── agents/ # 22 solidforge:<name> agent definitions (loaded by sf-subagents)
└── extensions/
├── sf-subagents/ # subagent tool + package agents discovery (16/8 concurrency, env-tunable); live streaming of child internals (tool calls / turns / elapsed / idle / text tail)
├── sf-hooks/ # tool_call/tool_result → python hook bridge (CLAUDE_PROJECT_DIR env)
├── sf-providers/ # credential bridge + the qwen-bailian route registration
├── sf-progress/ # csr run-progress footer strip (tails the ADR #61 sidecar; ambient run-level status)
└── sf-hetero/ # the hetero_doc_review tool — the different-family leg as a first-class tool (live per-provider panel; stdout verbatim as content)
Port provenance and per-milestone decisions: PORTING-PLAN.md (M0 spike → M4; now frozen as the lineage + divergence ledger). Live relationship contract with the CC reference implementation: docs/upstream-watch.md. Each skill's docs/ retains the upstream convergence trail; substrate divergences are logged in the skills' *.divergence.md.