Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .pylon/features.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,23 @@ decisions:
- Prime upstream exposes an equivalent generation-scoped, post-attach public proof that is false before attach and after invalidation.
- Pylon and Comet can remove the fork SDK token/accessor without enabling optional behavior from a server offer, version, or method presence.

nonpersistent-daemon-worker:
area: runtime-reliability
state: candidate
owner: shared
decision: retain
pylon_refs:
- https://github.com/pylon-code/prime-agent/issues/20
- https://github.com/pylon-code/pylon/issues/114
- https://github.com/rynfar/comet/issues/7
upstream_refs:
- https://github.com/PrimeIntellect-ai/prime-agent/tree/a903d4b6768f484bd6d459b7b0aa7dee38e461e2
fork_change: nonpersistent-daemon-worker-v1
upstream_support: Prime through a903d4b6768f has recoverable daemon workers and client-owned cleanup, but no capability-gated fresh worker mode that keeps create secrets, prompt payloads, correlation identities, transcripts, and snapshot caches out of durable state and permanently excludes that worker from recovery, adoption, relaunch, residency, and update snapshots.
revisit_when:
- Prime upstream exposes an equivalent frozen SDK token, exact create-only live-generation receipt, memory-only private retry and snapshot handling, and strict disabled-recovery provenance.
- Comet and Pylon can remove the fork token without weakening prompt privacy, worker-loss containment, owner cleanup, or ordinary-worker compatibility.

child-scoped-provider-identity:
area: runtime-reliability
state: shipped
Expand Down
12 changes: 12 additions & 0 deletions .pylon/upstream-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,15 @@ This ledger records Prime upstream evidence and the decision taken for each over
- Build/verify, attestation, and publication remain separate privilege domains. Publication writers do not checkout or execute repository/downloaded code. Normal attesters carry the one direct environment approval and OIDC/attestation writes; downstream draft/final jobs alone get contents write. Stable recovery uses a mutually exclusive zero-write direct approval and the old exact attestation. Actions and the reviewed attestation composite chain are full-SHA pinned. `pylon-preview` and `pylon-stable` use exact `pylon` custom-branch policies and explicit solo-maintainer approval. Active no-bypass tag ruleset `21950766` allows creation but prevents update/deletion of `pylon-build-*` and `pylon-stable-*` refs, including N-only sequence reservations. Immutable Releases remains enabled.
- Offline publication tests cover canonical bytes, closed current/historical recipes, rerun-stable preview run sequencing and consumer high-water, exact check/workflow-run proof, wrong signer/source/subject/invocation and missing-Rekor rejection, stable consumer rollback/equivocation, digest-chained history, append-only revocations, exact approval/content-writer graphs, action-chain pins, and publisher no-source-execution. The operator and independent-verification runbook is `docs/pylon-publication.md`.
- Revisit only if Prime provides a repository-neutral immutable publication primitive that fully preserves Pylon's protected-source, provenance, history, and withdrawal guarantees, or if Pylon deliberately replaces GitHub Releases with an equivalent verifiable transport.

## 2026-09-10 — schema-31 nonpersistent daemon-worker candidate

- Fork base: `pylon-code/prime-agent@68603ed89bb597cd715fd6a77bc1c39d7e110298`; upstream baseline remains `PrimeIntellect-ai/prime-agent@a903d4b6768f484bd6d459b7b0aa7dee38e461e2` / `v0.8.1`.
- Reviewed upstream daemon create, client-owned cleanup, command and worker recovery journals, worker authentication, descriptor loading, snapshot transfer caches, recoverable-owned adoption, update restart, and force-stop discovery. Upstream has no equivalent capability-gated mode or exact live-generation receipt.
- `nonpersistent-daemon-worker`: **retain** the schema-31 fork candidate. It accepts only a fresh client-owned, in-memory, tool-free, extension-free worker and proves `workerRecovery: "disabled"` only on the exact create response for the ready authenticated incarnation.
- Disabled create and correlated retry identity stays in bounded process memory as defensively cloned full requests with deep equality. Disabled creates have a 1 MiB per-request bound; the keyed retry store has both a 32-entry and 8 MiB cumulative input-byte cap; worker and supervisor JSONL lines have a 64 MiB ingress cap. The client snapshots each public command before any asynchronous handshake wait, and requires and clones the exact disabled create receipt before selecting private identity handling; disabled creates and every proof-bound request force transport-bound, no-replay client options even on a shared recovery-enabled client, while ordinary connections retain constant-size request fingerprints. No disabled request digest enters a journal. Correlated input is nonempty non-slash text only, has an 8 KiB UTF-8 bound, carries no images, and has no session JSONL. Worker and supervisor snapshot caches fail closed above a 16 MiB memory-only bound instead of spilling payloads.
- Version 3 descriptor plus exact `.nonpersistent` marker content binds disabled recovery provenance. Missing, malformed, downgraded, or inconsistent provenance is contained and retired rather than repaired into ordinary recovery. Authentication binds the expected mode after token and supervisor-generation validation, so an invalid token is not a remote worker-kill primitive.
- Disabled workers clear inherited tool, extension, and autonomous configuration; prove the effective runtime has no active tools, loaded extensions, autonomous continuation, or shell gates; and accept only a positive command allowlist. Contradictory explicit creates are rejected. Transcript-transforming and durable commands such as Bash, cron, `compact`, `export_jsonl`, and `refine` are rejected before worker dispatch and supervisor journaling. Disabled workers are excluded from command and worker journals, recovery, relaunch, retry, residency, attach-after-disconnect, recoverable-owned stores and MCP authority, and update snapshots. Each disabled worker is bound to its exact creating transport rather than only its logical client ID; loss of that transport starts immediate retirement, and proof-bound connections permanently reject reuse after transport loss as well as daemon recovery. Replacement and normal/adoptive shutdown retire them with PID, start-ID, and incarnation checks; descriptor-first cleanup preserves provenance across partial unlink, and forced CLI cleanup recognizes journal-less version 3 records.
- Ordinary schema-31 workers preserve existing undefined-identity command-journal lookup, recovery, caller-owned environment cleanup, recoverable adoption, and update behavior. No Pylon provider source change is needed for this private process-lifecycle slice.
- Validation includes protocol/client/CLI/mode/snapshot/supervisor units, strict provenance and auth tests, lost-response and collision tests, identity-safe stop tests, real normal-text privacy canaries across the agent artifact tree, replacement containment, affected recovery/update regressions, package build, and exact-artifact reproduction. The candidate remains unshipped until exact-head independent review and reproduction complete.
- Revisit when upstream exposes an equivalent frozen token, exact create receipt, memory-only privacy contract, strict disabled provenance, identity-safe retirement, and ordinary-worker compatibility.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Changed the build to compile from the committed model catalog instead of refetching it; run `npm run generate-models` explicitly to refresh `models.generated.ts`.
2 changes: 1 addition & 1 deletion packages/ai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"scripts": {
"clean": "shx rm -rf dist",
"generate-models": "npx tsx scripts/generate-models.ts",
"build": "npm run generate-models && tsgo -p tsconfig.build.json",
"build": "tsgo -p tsconfig.build.json",
"build:offline": "tsgo -p tsconfig.build.json",
"dev": "tsgo -p tsconfig.build.json --watch --preserveWatchOutput",
"dev:tsc": "tsgo -p tsconfig.build.json --watch --preserveWatchOutput",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Added a capability-gated nonpersistent daemon-worker mode for private fresh client-owned turns, with exact create proof, memory-only retry and snapshot handling, strict no-recovery provenance, and identity-safe cleanup ([#20](https://github.com/pylon-code/prime-agent/issues/20)).
- Kept disabled-worker prompts, create secrets, and correlation identities out of session files and recovery journals with exact receipt-bound in-memory retries, no effective tools, extensions, autonomous continuation, or shell gates, bounded ingress/retry memory, and a positive private command allowlist, while preserving ordinary daemon retry, recovery, and adoption behavior.
63 changes: 63 additions & 0 deletions packages/coding-agent/docs/sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,69 @@ if (!connection.supportsNegotiatedCapability("correlated_prompt_lifecycle_v1"))

`supportsNegotiatedCapability()` is false before attach, while a new attach or reattach is pending, after transport or attachment invalidation, and after disposal. It becomes true only after the same physical transport returns a validated client capability echo and the exact snapshot commit succeeds. `supportsCorrelatedPromptLifecycle()` remains server-offer evidence used to construct the attach request. It is not negotiation proof. Do not substitute a hello offer, method presence, attach success, or package version for the post-attach accessor. Correlated runtime frames are withheld until the attach-side echo commits and are discarded when the echo omits the capability. Pre-proof retention is bounded by both frame count and conservative cumulative structural weight; overflow fails the adapter closed without retaining or reporting attributed payload content. A chunked replacement uses the same count and weight bounds for frames held behind its atomic snapshot fence. New same-connection attachment admission, attachment-epoch change, transport loss, disposal, or matching session close retires that old fence before any later proof can publish; delayed old snapshot frames are ignored until a fresh attachment commits.

### Nonpersistent daemon workers

Hosts that need a private one-turn worker must require the package-root `nonpersistent_daemon_worker_v1` token and the same server hello capability before create. Then send one fresh create with `lifecycle: "client_owned"`, `workerRecovery: "disabled"`, `noSession: true`, and explicit `config.noTools: true` plus `config.noExtensions: true`. `sessionPath` and `continueRecent: true` are invalid. The raw protocol supports bounded same-supervisor convergence for a keyed client/command envelope; an unkeyed raw create is one-shot. Public `DaemonClient.request()` snapshots the command before any asynchronous handshake wait, then allocates and owns that command ID for the lifetime of its request. Callers cannot supply `id`, and must not start a second create after an uncertain return. A disabled create is always transport-bound and is never retained for reconnect replay, even when the `DaemonClient` is shared with an ordinary recovery-enabled connection.

```typescript
import {
DaemonAgentConnection,
DaemonClient,
PRIME_AGENT_SDK_FEATURES,
type DaemonNonpersistentWorkerCreateProof,
} from "@earendil-works/pi-coding-agent";

function isNonpersistentWorkerCreateProof(value: unknown): value is DaemonNonpersistentWorkerCreateProof {
if (!value || typeof value !== "object") return false;
const candidate = value as Record<string, unknown>;
return (
typeof candidate.id === "string" &&
(candidate.activeSessionId === undefined || typeof candidate.activeSessionId === "string") &&
typeof candidate.sessionId === "string" &&
candidate.workerRecovery === "disabled" &&
candidate.sessionFile === undefined
);
}

if (!PRIME_AGENT_SDK_FEATURES.includes("nonpersistent_daemon_worker_v1")) {
throw new Error("The local SDK does not support private daemon workers");
}

const client = new DaemonClient(socketPath, { maxInboundFrameBytes: 64 * 1024 * 1024 });
await client.connect();
if (!client.supportsServerCapability("nonpersistent_daemon_worker_v1")) {
throw new Error("The daemon does not support private daemon workers");
}

const response = await client.request({
type: "create",
lifecycle: "client_owned",
workerRecovery: "disabled",
noSession: true,
config: {
cwd: process.cwd(),
noTools: true,
noExtensions: true,
},
});
if (!response.success || !isNonpersistentWorkerCreateProof(response.data)) {
throw new Error("Private worker proof is unavailable");
}
const proof = response.data;
const connection = new DaemonAgentConnection(client, proof.activeSessionId ?? proof.id, {
ownedSession: true,
nonpersistentWorkerCreateProof: proof,
});
```

The `workerRecovery: "disabled"` field is an exact create-only receipt. List and attach summaries omit it. The receipt is returned only for the same ready, authenticated worker incarnation with a valid version 3 descriptor and `.nonpersistent` marker, the exact owner and root session, no session file, and no recovery or adoption state. A hello offer, schema number, create success without the receipt, attach success, or package version is not proof.

A disabled worker never creates a session JSONL or worker recovery journal. A disabled create is limited to 1 MiB, and keyed retry requests are cloned and compared only in supervisor memory with both a 32-entry cap and an 8 MiB cumulative input-byte cap. Pass the exact create receipt as `nonpersistentWorkerCreateProof` when constructing the owned `DaemonAgentConnection`; the adapter clones and revalidates it against the attached active/session generation before retaining private prompt retry requests as exact bounded in-memory clones. Ordinary connections continue to retain constant-size SHA-256 retry fingerprints. Disabled payloads are not fingerprinted. Supervisor and worker JSONL ingress reject a line above 64 MiB. Worker and supervisor snapshot caches remain memory-only and reject a transcript above 16 MiB instead of spilling it to disk. Correlated submissions accept only nonempty, non-slash text up to 8 KiB UTF-8 with no images. The fixed privacy-safe failures do not echo prompts, identifiers, paths, credentials, receipts, or digests.

The mode is deliberately narrower than an ordinary client-owned session. Effective tool and extension sets must be empty. Autonomous continuation and shell gates must also be disabled and empty. Inherited daemon defaults are cleared, contradictory explicit creates are rejected, and runtime proof fails closed if any tool, extension, autonomous continuation, or gate becomes active. A positive command allowlist admits only creation, live attachment controls, correlated submit/cancel/reconciliation, abort, and shutdown/owned cleanup. It rejects legacy prompt paths and transcript-transforming or durable commands such as Bash, cron, `compact`, `export_jsonl`, and `refine`. A disabled worker cannot change its root session, attach after disconnect, recover uncertain operations, retry, relaunch, become resident, enter recoverable-owned adoption, transfer MCP adoption authority, or participate in update-restart snapshots. Owner transport loss starts immediate identity-safe retirement; the worker is bound to its exact creating transport rather than only its logical client ID. A connection carrying the create proof rejects daemon-recovery options, forces every request to opt out of shared-client reconnect replay, and permanently treats every transport loss as terminal. Supervisor replacement, worker loss, normal shutdown, and `daemon stop --force` also retire the worker with process-incarnation checks. Ordinary recoverable workers keep their existing grace period, journal, hashed retry identity, replay, adoption, and update behavior.

After create, attach and separately require current-generation `correlated_prompt_lifecycle_v1` proof before using correlated prompt APIs. Do not resubmit across a transport or supervisor generation. Treat an unavailable create receipt, failed attachment proof, oversized snapshot, disconnect, or uncertain cleanup as terminal for that worker.

### Caller-owned daemon session environments and cleanup

Native multi-instance hosts must gate caller-owned daemon sessions with the exact `caller_owned_session_environment_cleanup_v1` contract. Require all three proofs:
Expand Down
Loading
Loading