Repository navigation
feat(extensions): add thin Pi /factory status, validate, and context commands - #14
Merged
Merged
Conversation
added 3 commits
October 6, 2026 12:13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Complete Factory CP-07 end to end from merged CP-06 main c241673. Captain's exact current instruction: "do not stop until cp 7 and 8 are end to end complete fully and merged as per the technical specs". This task is ONLY CP-07; CP-08 follows accepted CP-07 landing. Worker never merges; Firstmate has concrete captain merge authority for both checkpoints, not standing autonomy or deployment/discard/login authority.
Authoritative scope: BUILD_PLAN.md CP-07, COMPLETION.md, PROJECT.md, ARCHITECTURE.md, docs/CONTRACTS.md, docs/INTEGRATIONS.md, docs/WORKFLOW.md and existing skills/factory/SKILL.md. The deliverable is a THIN Pi extension at extensions/factory.ts and package registration providing /factory status, /factory validate, /factory context as wrappers around proven Factory CLI. No /factory run, scheduler, worker launch, task state ownership, model router, new daemon/background process or duplicate shipping controls. Preserve CLI semantics/output/errors/exit statuses, argument-array subprocess boundaries, scope/freshness/budget/no-secret protections, spaces in paths and offline normal operation. Register discovery/reload correctly for CURRENT installed Pi, not assumed historical SDK. Write invalid/missing/extra/unsupported argument tests first, exact command parity positives and failure tests, and actual installed-Pi load/reload/smoke evidence (not mocked-only callbacks). Feature parity plus no new background process is CP07 gate.
Follow global CTX intent-document policy in YOUR isolated worktree: main has no .ctx workspace and Firstmate will not initialize main. Deliberately index only authoritative project-intent Markdown with offline verified BAAI/bge-small-en-v1.5. Use one document-qualified strict semantic CP07 context request when initialized; resolve conflicting/partial/omitted norms by reading originals, never claim semantic COMPLETE from partial. Follow normative source cross references. For Pi extension implementation read complete installed Pi docs extensions.md, packages.md and related linked API docs/examples before coding; current installed root is /home/ansh/.nvm/versions/node/v24.20.0/lib/node_modules/@earendil-works/pi-coding-agent, docs/examples resolved there. No copying generic docs into project memory. Do not change shared Pi installation or auth settings. Existing graph if any is a locator only; no unrequested graph-generation subsystem.
Use current source/tests and prior docs/probes CP00-CP06 as evidence, not unquestioned verdicts. CP06 final report data/factory-cp06-pr12-audit/report.md and landing receipt data/factory-cp06-complete/landing-receipt.md in /home/ansh/firstmate-factory establish preserved security protections/limitations. Do not weaken no-range successful-original-read condition, mount/FD/provenance/cleanup/read-only auth controls. CP06 null normalization is denied by final audit, not universal pre-execution raw-null rejection; STRICT_AGENT remains PARTIAL separately from passing STANDARD ten-pack. Product-wide Linux/Windows limits must remain honest. Do not rerun real credential probes or inherited process-memory attacks; security negatives only disposable literal DUMMY data/processes.
Checkpoint evidence must record executed commands/exits/output paths/tested exactGitSHA/date/reviewer, actual Pi version+reload command and observed statuses, CLI parity and foreground-only execution; failed/unrun is notpassed. Add docs/probes/CP-07.md and update task-appropriate documentation/package instructions without manufacturing past proof. BUILD_PLAN CP06 unchecked gate may be accurately reconciled against confirmed landed exact-head receipts; do not alter original normative acceptance contract or assert whole Factory/V1 complete. No broader docs migration. Commit first implementation, then Firstmate invokes no-mistakes; preserve all pipeline fix ancestry and validate finalhead. Final format/lint/typecheck/test, actual extension reload/smoke/parity and existing required regressions must pass, CIgreen fullPRURL/head/risk/evidence required.
Validation safety: never use or reconfigure shared/default no-mistakes daemon. Establish supported dedicated task-local NM_HOME/config/daemon under ignored .factory/state in YOUR copy with explicit environment before any run. Firstmate authorizes starting only that positively identified task-local daemon through supported commands. Keep task-local config/models stable; use existing native signed-in validator through supported model/provider surface if needed, not unproved shared/default login. CP06 receipt for setup mechanics data/factory-cp06-complete/brief.md may be read, but never copy credentials or couple to its daemon/home. No auth contents reads/export/copy/hash/refresh, new login, shared/global config writes or tool updates. Existing scoped publishing setup may use GH_CONFIG_DIR=/home/ansh/.config/gh and GIT_CONFIG_GLOBAL=/home/ansh/.gitconfig without exposing contents. Actual missing capacity/auth errors -> promptly report supported command/output/scope, never silent model/backend fallback. Current relaunched outer worker is Pi openai-codex/gpt-6.1-sol High in the same harness (accepted supersession after the prior usage-limit); catalog supported, provider quota stale/unknown despite captain reset report, not guaranteed capacity.
Routine accepted-intent fixes are already authorized in scope and must proceed via Firstmate decisions immediately, not extra captain waits. For any active ask-user gate supply exact run/head/step/finding IDs/full finding text, precise Fix consequence and exact supported respond command, then wait for Firstmate, not direct captain. You own every no-mistakes run/respond and synchronous return; no --yes, skip, blanket approval, manual edits while custody active, abort/reset/discard/duplicate code runs. Do not create separate manually stacked review; normal no-mistakes owns fresh review/test/doc/publish/CI. No app creation or CP08 implementation in this task; no deployment/remote creation beyond Factory's established origin.
Accepted Firstmate decisions: initialize ONLY independently owned standalone validator clone under this task's ignored .factory/state/v with own .git/common directory, NM_HOME=.factory/state/n, HOME=.factory/state/h. Do not alter the outer linked worktree's inherited no-mistakes remote (shared Git config). Standalone clone origin remains the established Factory origin. Only this positively identified dedicated daemon may be started/reloaded via supported commands; do not copy or control CP06 daemon/home/auth. Use supported native signed-in validation surface with explicit scoped GH_CONFIG_DIR=/home/ansh/.config/gh and GIT_CONFIG_GLOBAL=/home/ansh/.gitconfig; no credential copying/contents reads/export/hash/refresh/new login/global writes. Current dedicated validator is explicitly native Claude opus/high with existing CLAUDE_CONFIG_DIR=/home/ansh/.claude; no silent fallback. Keep configuration stable. Firstmate002 explicitly steered sole full no-mistakes validation from exact implementation bc1dd5d. You must preserve all pipeline fix ancestry and rerun final-head proofs; Firstmate alone merges after independent acceptance.
Implementation choices: wrapper uses the source entry extensions/factory.ts explicitly registered with the skill, host SDK peer plus pinned0.99.2 development SDK. Its Promise Pi slash handler cannot set a per-command OS exit code on persistent Pi: preserve separate exact stdout/stderr/exit_code/killed fields in factory-result.details and display CLI exit label, triggerTurn:false. Never exit persistent Pi or confuse RPC prompt acceptance/Pi exit with CLI status; CLI remains direct OS-status interface. Supported-command option parsing remains the CLI's existing semantics (including permissive global flags); only verb whitelist and argv quoting framing live in extension. No shell expansion. Current installed Pi root is explicit above; optional real CTX fixture proof initializes only two normative originals and offline verified model. No new product background process; the authorized preexisting tool's dedicated validation daemon is outside Factory runtime.
Development evidence (not final pipeline-head certification): outer copy9 ignored .factory/state/cp07-evidence/final-bc1dd5d0735d47ea3751cf428f7b6e6d5fa662e9-r2/receipt.json records exact implementationhead date/reviewer/commands/outputs: npm ci, format/lint/typecheck190/190 tests zero skips, actual installed Pi0.99.2 package/command/runtime replacement, exact CLI parity and real offline semantic CTX success/budget/stale negatives, actual installed CLI/TUI /reload, CP06 STANDARDten-pack/P07/DUMMY auth-security and all cleanup negatives all exit0. Earlier failed proof attempts are retained separately, not passed. CP06 tests/proofs require separately pinned0.85.1 SDK under each proof checkout's .factory/state/cp06-sdk, NOT the current0.99.2 development SDK; use docs/probes/CP-06.md supported installation and explicit CP06_PI_PACKAGE_ROOT/CP06_PI_BIN. CP06_OUTPUT must remain under .factory/state/cp06-correction/ to satisfy inherited safety guard. Do not rerun any real credential/model acceptance probe in this task.
What Changed
Adds
extensions/factory.ts, a Pi extension registered alongside the Factory skill underpiinpackage.json. The host SDK is a peer dependency and the development SDK is pinned to0.99.2. The extension registers only/factory, which acceptsstatus,validate, orcontext <ID>. It splits the quoted input into arguments without any shell expansion, then runs the built CLI once in the foreground: the Pi host's Node is spawned with an argument array andshell: false.factory-resultmessage withtriggerTurn: false. The message shows unmodified stdout/stderr plus anexit: Nlabel. Its details keepstdout,stderr,exit_code,signal, andkilledas separate fields.FACTORY_ARGUMENT_ERROR(exit 2).FACTORY_RUNTIME_UNAVAILABLE(exit 3) without starting any process./factory run.Adds tests in
test/cp07-extension.test.mjsandtest/cp07-pi-smoke.test.mjscovering:Also adds two proof scripts and their npm entries:
scripts/cp07-pi-smoke.mjs(proof:cp07:pi) for an installed-Pi load/parity smoke test, andscripts/cp07-pi-reload.py(proof:cp07:reload) for a real TUI/reloadproof. Format, lint (including itsshell: trueban), and typecheck now also coverextensions/..gitignorenow ignores Python bytecode.Adds
docs/probes/CP-07.md, covering the installed Pi version, the extension's boundaries, proof commands, and remaining limits. Updates README,docs/INTEGRATIONS.md, andskills/factory/SKILL.mdwith how to use the optional Pi package. InBUILD_PLAN.md, checks off the CP-07 steps and the CP-06 gate, with a note recording how the CP-06 gate was reconciled against its landed PR13 receipt.🤖 Generated with Claude Code
Risk Assessment
✅ Low: The fixes check out against the code: the extension spawns the CLI directly (argv array,
shell: false), decodes output once, reports signals instead of exit 0, refuses non-Node hosts, and the reload proof now checks exit labels with markers that can't come from an earlier redraw, so only a rare sync-spawn error path is left unwrapped.Testing
After a fresh build at 77332a8, the targeted CP-07 extension and real-SDK smoke tests passed (23/23). That covers argument rejection and delegation, UTF-8 chunk boundaries, signal and nonzero exits, refusal of non-Node hosts, and no process started at registration. A standalone smoke against the installed Pi 0.99.2 showed exact CLI parity, runtime reload, and no model, network or background-child activity. A real installed-Pi TUI session showed the correct CLI exit labels before and after
/reload, with a unique post-reload marker. Git now ignores generated bytecode and none is tracked. The CP-06 SDK-boundary tests passed 15/15 with the pinned 0.85.1 SDK. The only gap is the optional real-CTX semantic mode, which could not run here because the sandbox has no verified CTX model. All transient artifacts were removed.Evidence: Installed Pi 0.99.2 TUI /reload proof summary (observed CLI exit codes)
Evidence: Readable TUI transcript (ANSI-stripped) showing /factory outputs, exit labels, Reloaded, and post-reload invocations
Evidence: Raw PTY bytes from the installed Pi TUI session
Evidence: Installed Pi 0.99.2 smoke: CLI parity cases, reload, zero model/network/background children
Evidence: CP-07 extension + SDK smoke node:test output
Evidence: Git ignores generated __pycache__ bytecode
Evidence: CP-06 SDK boundary regression with pinned 0.85.1
/home/ansh/.treehouse/Factory-86709f/9/Factory/.factory/state/n/evidence/01M48JTDMY09C8AKNQPPRZCMT2/cp07-installed-pi-smoke-real-ctx.log)Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
extensions/factory.ts:70- The wrapper depends on Pi'spi.exec, and that helper does not pass the CLI's exit status and output through faithfully. This contradicts the authoritative requirement to "Preserve CLI semantics/output/errors/exit statuses" and the CP-07.md claim thatdetailsholds "unmodified separate streams, numeric exit_code". In the installed Pi 0.99.2,dist/core/exec.jsresolves withcode: code ?? 0, andwaitForChildProcessreturns a null code when the child is ended by a signal.killedis only true when Pi itself killed the process, which never happens here because the wrapper passes no timeout or signal. So if the Factory CLI is killed externally (OOM, SIGKILL, SIGSEGV),/factory statusshowsexit: 0withdetails.exit_code: 0, killed: false, which looks like success even though the direct CLI would report a signal. Separately,stdout += data.toString()decodes each pipe chunk on its own. When output is larger than about 64 KiB, for example a bigstatus --jsonor a context pack with a large--byte-budgetcontaining non-ASCII text such as the em-dashes used throughout these docs, a multi-byte character split across chunks becomes U+FFFD. JSON still parses, but stdout no longer matches the CLI byte for byte. The unit test covering 250 KB output uses a mocked ASCIIexec, and the real smoke outputs are small, so neither case is tested. Fix: spawnnode:child_processdirectly with an argv array andshell: false, collect Buffers and decode once, and report thesignal(or a non-zero code) whencodeis null. Alternatively, at minimum treat a null code as failure. Update CP-07.md to match.extensions/factory.ts:70-process.execPathis assumed to be a Node binary. Installed Pi explicitly supports running as a Bun-compiled binary (dist/config.jsisBunBinary), and the documented primary installer iscurl -fsSL https://pi.dev/install.sh | shin docs/quickstart.md. In that setupprocess.execPathis the Pi binary itself, so/factory statusrunspi /…/dist/src/cli.js status. Per docs/cli.md, redirected stdout puts Pi in print mode and sends the positional arguments as a prompt. The result is a nested Pi agent run that uses the user's credentials, makes a model request, and may use tools. That conflicts with the CP-07 gate ("no new background process", "not model calls"), and the Factory CLI never runs. The proofs only cover npm-installed Pi on Node, so this path is untested. Fix: fail closed with FACTORY_ARGUMENT_ERROR (or a similar error) whenprocess.versions.bunis set orprocess.execPathis not Node, or resolve an explicit Node executable, and record this limit in CP-07.md.scripts/cp07-pi-reload.py:74- The TUI/reloadproof only checks that an output substring appears in the PTY bytes after each input. It never checks theexit: Nlabel, so a post-reload/factory validatethat printed the header but failed would still pass. The recordedstatusesonly repeat the expected substring rather than CLI exit codes, although CP-07.md and the intent ask for observed statuses. The second/factory validatealso expects the same text as the first, so a full-screen redraw after/reloadthat repaints earlier transcript lines could satisfy it without the reloaded command running. Fix: match on the exit label as well (for exampleexit: 0/exit: 2), and use a distinguishing post-reload marker or count new occurrences.🔧 Fix: Spawn CLI directly, reject non-Node Pi hosts, tighten reload proof
1 warning still open:
scripts/__pycache__/cp07-pi-reload.cpython-312.pyc:1- The review-fix commit 3d4dc49 added a generated CPython 3.12 bytecode file,scripts/__pycache__/cp07-pi-reload.cpython-312.pyc(8599 bytes, binary). It was produced when the reload proof was imported or run during the fix round, and.gitignorehas no__pycache__/or*.pycrule (git check-ignoreexits 1). The file goes stale wheneverscripts/cp07-pi-reload.pychanges, depends on the interpreter version, and is not a source, proof, or evidence artifact. Committing it also goes against the repo's rule that runtime artifacts stay out of tracked paths. Fix:git rm --cached scripts/__pycache__/cp07-pi-reload.cpython-312.pyc(delete the directory) and add__pycache__/and*.pycto.gitignore.🔧 Fix: Untrack generated Python bytecode and ignore pycache artifacts
1 info still open:
extensions/factory.ts:97-runClionly handles spawn failures that Node reports through the asynchronouserrorevent (ENOENT, EACCES, EAGAIN, EMFILE, ENFILE). For any other libuv spawn error,child_process.spawnthrows synchronously, and here the throw happens inside thenew Promiseexecutor. I confirmed this locally: spawning withcwdset to a file throwsENOTDIRsynchronously, and an oversized argv gives E2BIG. The result is that the slash handler rejects with a raw exception and nofactory-resultmessage is sent. That contradicts the contract in CP-07.md and README, which says a wrapper-side start failure producesFACTORY_RUNTIME_UNAVAILABLE(exit 3) withdetails. This is not a false success, and the triggers are rare. Fix: wrap thespawn(...)call in try/catch and resolvefailure("FACTORY_RUNTIME_UNAVAILABLE", error.message, 3). A DUMMY test with a file as the cwd would cover it.scripts/cp07-pi-smoke.mjs:134- The optionalCP07_REAL_CTX=1smoke mode failed (exit 1) in this sandbox. The failure happens before the extension is ever compared: the direct Factory CLI itself returnsCONTEXT_BLOCKED: CTX returned an unusable response(exit 3). This sandbox's HOME (.factory/state/h) has no verified offline BAAI/bge-small-en-v1.5 model. The previous review-fix round hit the same environment limit, and docs/probes/CP-07.md already records it as not passed. Context-pack parity with real semantic retrieval at this head therefore still depends on the outer final-head proof with a provisioned CTX model. The non-semantic context paths passed here (missing ID, extra arg, zero budget, absent ctx-bin).npm run build(exit 0, HEAD 77332a8b2f912ddaca577c2df59568ae7afdc93b)node --experimental-import-meta-resolve --test test/cp07-extension.test.mjs test/cp07-pi-smoke.test.mjs: 23/23 pass, 0 skipped. Covers unsupported, missing and extra arguments, quoting, NUL, spaces, Windows paths, metacharacters, large output, UTF-8 split across pipe chunks, SIGKILL reported as 137 with the signal name, refusal of a non-Node or Bun host, unavailable cwd, and parity with real SDK reloadCP07_PI_PACKAGE_ROOT=<installed pi 0.99.2> PI_OFFLINE=1 node scripts/cp07-pi-smoke.mjs(exit 0): 20 cases with exact stdout/stderr/exit parity, reload_replaced_runtime true, 0 model requests, 0 network calls, 0 background childrenpython3 -B scripts/cp07-pi-reload.py --pi-bin $(which pi) --output <evidence>/reload(exit 0): real installed Pi 0.99.2 TUI. Observed CLI exits 0, 2, 2, then/reload, then 0, 0, 2 with a unique POSTRELOAD_DUMMY marker; Pi exited 0Rendered an ANSI-stripped TUI transcript. It shows the pre-reload transcript being redrawn and, separately, the new post-reload invocationsBytecode policy: ranpy_compileon scripts/cp07-pi-reload.py, thengit check-ignore -v(matched .gitignore:6__pycache__/),git status --porcelain --untracked-files=all(clean), andgit ls-tree(no tracked .pyc)Installed the pinned CP-06 SDK 0.85.1 under ignored .factory/state/cp06-sdk as documented in docs/probes/CP-06.md, then rannode --experimental-import-meta-resolve --test test/cp06-pi-dependency.test.mjs test/cp06-review-boundaries.test.mjswith CP06_PI_PACKAGE_ROOT/CP06_PI_BIN set: 15/15 pass, 0 skipped. This checks that the new 0.99.2 dev SDK does not disturb CP-06 SDK selectionCP07_REAL_CTX=1 ... node scripts/cp07-pi-smoke.mjs(exit 1: the direct CLI returned CONTEXT_BLOCKED because this sandbox has no verified CTX model)Cleanup: removed the temporary cp06-sdk, npm cache, empty auth-security/cp06-correction dirs and scripts/__pycache__; worktree is clean✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.