pi-posthorse context-window extension
Type: types/agentic-system-analysis-result.md
Run identity
Run state: kb/reports/state/agentic-system-analysis/AAS-2026-09-25-pi-posthorse-01/run-state.md
Generated review: kb/agentic-systems/reviews/pi-posthorse.md
Memory analysis report: kb/reports/state/agentic-system-analysis/AAS-2026-09-25-pi-posthorse-01/memory-report.md
Memory analysis report SHA-256: accce5e53cd7e074242bf7718b94680501e167c77bd22d72dd02cf64ce0098e0
Boundary and evidence
Evidence basis: source code and shipped documentation at 5bdba3536e186a7be845844d0398c3485a7f8e2b, frozen 2026-09-25; no observed run or causal experiment. Target class: host integration; boundary kind: complete artifact, partial loop. Includes the Pi extension's context-window policy, native API calls, notes/history tools and recovery selection. Excludes the isolated Codex adapter prototype and the external Pi fork's implementation, other extensions, provider internals and deployed agent behavior. The source names a qualified fork revision, but that repository was not part of the evidence allowlist. Thus native persistence, atomic rollover and actual model delivery remain external contracts where extension source cannot verify them.
Source allowlist: https://github.com/fitchmultz/pi-posthorse only, accessed by full-commit Git reads at /home/zby/llm/commonplace/related-systems/fitchmultz--pi-posthorse. No prior review, ingest, matrix or linked external code supplied evidence. Node and the required Pi fork SDK are dependencies; packages were not installed.
Source register
| Source ID | Kind | Identity/location | Revision | Evidence layer | Inspected scope | Citation anchors | Access gaps and conclusion prevented |
|---|---|---|---|---|---|---|---|
| SRC-1 | Git | https://github.com/fitchmultz/pi-posthorse |
5bdba3536e186a7be845844d0398c3485a7f8e2b | implementation | native capability checks, budgets, initialization/guidance/reminder/context/rollover hooks, tools and memory paths | index.ts:130-143,788-1083; index.ts:1-1340; ui.ts:1-59,113-194; test/native.test.mjs:143-175,244-284,422-459; test/integration/posthorse-in-pi.test.ts:80-120,272-307 |
native host/provider implementation excluded; no executed continuity test |
| SRC-2 | Git | https://github.com/fitchmultz/pi-posthorse |
5bdba3536e186a7be845844d0398c3485a7f8e2b | doctrine/design | README and generated guidance | README.md; index.ts:826-846 |
claims of host atomicity/persistence not independently verified |
Shared records
Components
CMP-1 — External Pi host supplies native context APIs, session journal/projection, tool dispatch, model configuration and usage. Its distributed-parametric consumer model is not selected or trained by the extension; identity pinning, parameter changes and provider internals each have conclusion status: uninspected. The extension uses current model context size, not exact weight identity. Source: SRC-1, index.ts:130-143,788-824.
CMP-2 — Posthorse TypeScript extension supplies symbolic policy, file operations and bounded context selection. Implementation conclusion status: wired. It checks for newContext, compaction settings, system prompt and publishLocalFile; a missing API throws. The current host grant set and filesystem isolation are external. Source: SRC-1, index.ts:130-143.
throw new Error("Posthorse requires the fitchmultz/pi fork with native context windows and publishLocalFile (see README)."); ---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
Operative objects
OBJ-1 — notes. UTF-8 file contents under the resolved .pi/notes directory; readable prose or arbitrary caller-authored text, no enforced semantic schema or rationale field. Git metadata locates a shared root; notes are not required to be committed. Lineage: authored and legacy-imported. Producer: model/tool caller or human file editor. Consumer: model via requested notes results. Authority: advisory knowledge; semantic advice can guide continuation, but file presence does not make it a system instruction. Implementation status: wired; human editing is afforded by plaintext storage. SRC-1 index.ts:200-258,1083-1186; SRC-2 README.md:90-101.
const path = safeJoin(relative); mkdirSync(dirname(path), { recursive: true }); await publishLocalFile(path, params.content, signal); return textResult(`Wrote ${path}`, [], { kind: "note-write" });---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2bconst existing = existsSync(path) ? readFileSync(path, "utf8") : ""; const separator = existing && !existing.endsWith("\n") ? "\n" : ""; appendFileSync(path, `${separator}${content.replace(/\n?$/, "\n")}`); return textResult(`Appended to ${path}`, [], { kind: "note-append" });---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
OBJ-2 — native transcript and projected entries, retained parent identity. Raw JSONL entries include message text/thinking, tool calls/results, image payloads, custom messages, context windows, host compaction/branch summaries and context edits. The extension reads host branch objects or JSONL files and makes a normalized text view; this is not a second durable summary store. Raw image payloads remain distinct from readable image-count/type summaries. Host projection is an external input whose correctness is uninspected. SRC-1 index.ts:71-111,178-198,277-303,367-415,650-658; SRC-2 README.md:56-57,99-100.
function textResult(text: string, images: ImageLike[] = [], display?: PosthorseDisplay) { return { content: [{ type: "text" as const, text }, ...images], details: display }; } ---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
OBJ-3 — explicit or automatic context handoff, retained combined parent identity. A string in the host context_window record, passed as newContext.handoff. Explicit content is authored; automatic content is trace-extracted. The extension constructs and caps payloads, while host persistence and fresh-model delivery are claimed. Advice/evidence at the model, not a verified account of progress. SRC-1 index.ts:296-298,608-741,1003-1050; SRC-2 README.md:54-56.
new_context. Requests an atomic rollover after the complete tool batch succeeds. An optional handoff is persisted and becomes the first state of the fresh window. If a sibling tool in the same batch fails, Pi does not commit the boundary; the checkpoint reminder still applies. ---README.md@5bdba3536e186a7be845844d0398c3485a7f8e2b
OBJ-4 — reminders. Generated steering text plus symbolic fingerprint {windowId, contextWindow, reserveTokens}. Retained in the host journal by contract; active-input filtering does not remove journal history. Model consumer receives checkpoint instructions; extension consumes fingerprint metadata for reminder suppression and withdrawal. SRC-1 index.ts:745-786,939-1000. Implementation status: wired; durable journaling is claimed.
pi.sendMessage( { customType: REMINDER_TYPE, content: `[posthorse] Checkpoint now: ${(budget.rolloverAt - usage.tokens).toLocaleString("en-US")} tokens remain before Pi's automatic rollover line. Stop normal work, save goal/progress/decisions/next steps, then call new_context now. This reminder is best-effort; a large turn, overflow, restart, or smaller model can reach rollover without one.`, display: true, details: fingerprint, }, { deliverAs: "steer" }, );---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
OBJ-5 — context edits and attached images within OBJ-2. targetId, replacement, replacement-entry identity, and host projection determine recovery content; null replacement withdraws an entry. History reads replacement-entry IDs as replacement text/images and original-entry IDs as raw content. Images are opaque payloads delivered alongside text; MIME/base64 containers and previews do not establish a complete controlled representational-form set. SRC-1 index.ts:94-108,299-301,367-374,619-633,1298-1323. Status: wired for extension treatment, uninspected for host edit creation/projection semantics.
const text = flattenEntry(entry); if (!text || !entry.id) return undefined; const images = imagesOf(entry.type === "context_edit" ? entry.replacement?.content : entry.type === "message" ? entry.message?.content : entry.content); return { entry, windowId, text, images }; ---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
OBJ-6 — the automatic recovery form of OBJ-3. Derived text retains owner/coordination classification, timestamps, history IDs, requested/admitted arguments, bounded tool evidence, omission statements, caution and an optional possibly stale prior checkpoint. It contains no image bytes; images get history pointers. It does not infer new progress facts. Store and later consumer are the host handoff route. SRC-1 index.ts:494-545,549-741. Construction status: wired; persistence/delivery status: claimed.
function formatPriorCheckpoint(entry: EntryLike | undefined, limit: number): string | undefined { const handoff = entry?.handoff?.trim(); if (!entry || !handoff) return undefined; const id = entry.id?.slice(0, 120) ?? "unknown"; const header =
[older checkpoint; possibly stale | context-window entry ${id}]; if (handoff.startsWith(AUTO_HANDOFF_PREFIX) || handoff.startsWith(LEGACY_AUTO_HANDOFF_PREFIX)) { return boundedBlock(header,Prior automatic recovery text is not nested here. Use history read with entry ${id} if needed., limit); } return boundedBlock(header, handoff, limit); ---index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
OBJ-7 — access metadata and transient selection state. Window maps, SHA-256 file keys, query/scope-bound cursors, page offsets and image offsets identify retained content; pending-page accounting reserves context across tool siblings. They are symbolic access structures, separate from note/history payloads. Storage: transient memory and encoded returned metadata; any later tool-result persistence is host-owned. Consumers: extension paging/routing/ranking code and human renderers. SRC-1 index.ts:315-374,867-917,1211-1291,1294-1323; ui.ts:4-11,43-56. Status: wired.
/* Display-only facts and offsets into content, never a second copy of a note or history page. / ---
ui.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b// Parallel siblings are not in native usage yet; sequential results must not be counted twice. if (usage != null && previousPageUsage != null) { pendingPageTokens = Math.max(0, pendingPageTokens - Math.max(0, usage - previousPageUsage)); } previousPageUsage = usage; const remaining = pageCapacity(ctx, activeToolTokens()) - pendingPageTokens; const chars = Math.min( MAX_HANDOFF_CHARS, Math.max(0, remaining - PAGE_MARGIN_TOKENS) * 4 - imageCount * ESTIMATED_IMAGE_CHARS, );---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
Routes
RTE-1 — Session start checks native capabilities. Before agent start, the extension adds stable context-management guidance through a native prompt section; if an earlier extension forces a full prompt, it appends guidance to that prompt. Implementation conclusion status: wired. Host owns actual model invocation and prompt precedence; policy strength is instructional, not behavioral enforcement. Trigger is host lifecycle event, next-step owner host, return prompt configuration. No memory revision occurs here; static guidance is not accumulated memory. Source: SRC-1, index.ts:924-937.
if (event.systemPromptOptions.forceSystemPrompt !== undefined) { return { systemPrompt:
${event.systemPrompt}\n\n${guidance}}; } event.systemPromptOptions.sections.posthorse = guidance; ---index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
RTE-2 — Turn end uses native usage and effective compaction settings to decide whether to issue one fingerprinted checkpoint reminder. Disabled/unsupported budgets, error/aborted turns, a successfully requested rollover or already crossed threshold skip it. Context hook removes stale reminder messages from active input while preserving raw history. On the pre-auto-compaction hook the extension computes a safe handoff budget, builds a bounded recovery record from the current projection, and returns a newContext request; an unsupported budget or nonfitting record leaves the host's own behavior in control. Implementation conclusion status: wired. Reminder guarantee strength: best effort; rollover persistence/atomicity belongs to the external host contract. Source: SRC-1, index.ts:939-1014.
if (budget && !budget.supported) return undefined; const limit = freshPayloadChars(native, activeToolTokens(), event.pendingMessages); if (limit < MIN_PAGE_CHARS) return undefined; const projected = (ctx as ExtensionContext).sessionManager.buildSessionProjection().entries; const handoff = buildAutoHandoff(event.branchEntries, projected, limit); if (handoff.length > limit) return undefined; return { newContext: { handoff } }; ---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2bconst stale = (message: (typeof event.messages)[number]) => message.role === "custom" && isReminderType(message.customType) && (!native.getCompactionSettings().enabled || reminderIsStale(message.customType, message.details, fingerprint, branch)); if (event.messages.some(stale)) return { messages: event.messages.filter((message) => !stale(message)) };---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
Automatic recovery has its own detail on RTE-7. Reminder selection uses window/model/reserve fingerprints, not semantic matching. Filtered records remain in raw history; delegated visibility and actual model response to reminders are uninspected. No task-state truth is admitted by this route.
RTE-3 — Model/operator calls new_context with optional handoff. Extension trims input and rejects it if it exceeds the fresh model-aware capacity; otherwise returns tool output plus a newContext payload. The host is next-step owner and commits the boundary under its tool-batch protocol. Implementation conclusion status: wired for request/validation; completion of a persisted window transition is afforded by the required host, unobserved. An extension tool result reporting a request is not itself proof the boundary committed. Source: SRC-1, index.ts:1016-1052.
if (trimmed && trimmed.length > limit) { throw new Error(
Handoff is too large for the active model (${trimmed.length.toLocaleString("en-US")} characters; limit ${limit.toLocaleString("en-US")}). Save fuller state in notes, then retry with a shorter handoff or no handoff., ); } ---index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
Handoff content is arbitrary caller-authored continuation text, possibly including reasons; no schema requires rationale. Its later consumer is the fresh host model through BAP-1, with host-claimed persistence and delivery. Explicit request has no semantic selector, expiry or truth gate. Sibling batch failure prevents commit under the host contract; source does not inspect that enforcement. Human/model can propose another handoff; no retained revision history is implemented by this tool itself.
RTE-4 — notes operations. The active model calls list/read/search/write/append; list/read/search return budgeted pages. Case-insensitive substring search scans lines with path/line-number excerpts; no embedding index is constructed. Replacing a file affords evolving its content; clearing with empty text removes current content without extension-managed version history. Append adds a newline-terminated record. The tools do not automatically extract notes from conversations. SRC-1 index.ts:1083-1186. Status: wired; content authoring/curation policy: afforded.
Notes begin with human/model-authored content. write passes a complete string to native publication; it does not merge concurrent versions. append writes one newline-terminated record and preserves existing text. The README limits replacement guarantees: failure before publication preserves the previous file, but hardlinks/open handles, ACLs, extended attributes and power-loss durability are not guaranteed; those host guarantees were not independently inspected (SRC-2 README.md:92). A caller can revise a note or clear it; there is no version/tombstone protocol in the inspected notes switch. RTE-4 does not require reasons for advice, provenance headers, timestamps or review before adoption. If a caller includes reasons, later requested reads can return them, subject to paging. File editability is a human adoption surface, not evidence of actual human review.
Immediate return is mutation confirmation or budgeted file content; later read-back is explicit pull via BAP-2. Files survive sessions under the resolved project root; expiry and delegated grants are uninspected. Native replacement failure recovery is host-owned. Guidance is continuity advice, not a theory test; no semantic rejection or empirically grounded successor selection is wired in this switch.
RTE-5 — history operations and context-edit readback. The active model requests a query or entry ID; code returns normalized text and requested images, with pagination. Current branch is default. all searches eligible JSONL files in the active session directory, includes project-attributable nested subagents, and retains each file's fork copies. Archived reads also use this scope; a bare entry ID first checks the active branch, then eligible files. Full file-qualified IDs avoid ambiguity. SRC-1 index.ts:277-471,1188-1340. Status: wired. This is requested pull even though selection and formatting are automatic.
const allowed = file === currentFile || (parent ? await belongs(parent) : !!header.cwd && resolve(header.cwd) === cwd); visible.set(file, allowed); return allowed;}; for (const file of files) { if (fileKey !== undefined && historyFileKey(relative(dir, file)) !== fileKey) continue; if (await belongs(file)) yield file; ---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2blet priority: 0 | 1 = entry.type === "context_window" || entry.type === "compaction" || entry.type === "branch_summary" || (entry.type === "custom_message" && isReminderType(entry.customType)) || (entry.type === "message" && entry.message?.role === "toolResult" && isRecoveryTool(entry.message.toolName)) ? 1 : 0; ---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2bif (message.role === "bashExecution") { // Pi keeps these out of every model's input on purpose; do not smuggle them back in through history. if (message.excludeFromContext === true) return "[bashExecution] (excluded from model context by Pi)"; return `[bashExecution] $ ${message.command ?? ""}\n${message.output ?? ""}`;---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
The route returns text/images and offsets immediately, with later model consumption through BAP-2. Source history survives independently of active context. Selection is requested lexical query or identity; entry priority, per-file reverse order and current/all scope apply. Output budget refusals preserve cursor/offsets for retry. Stale cursors can fail after source files change; no lifetime guarantee or semantic truth test is imposed. Cross-agent files may be visible by project ancestry, not universally; deployed permissions remain uninspected.
RTE-6 — Context meter returns native usage estimates and separates automatic-rollover line from configured context limit. If no usage is available it reports that uncertainty. Implementation conclusion status: wired; provider rejection boundary uninspected. Trigger explicit request, deterministic arithmetic owner, context current host settings, immediate tool result, no retained knowledge revision or later read-back route. Source: SRC-1, index.ts:1054-1081.
if (!usage || usage.tokens == null) return textResult("Context usage is not known until the next model response.", [], { kind: "context" }); ---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
RTE-7 — automatic trace-fed recovery in RTE-2. Trigger: host threshold/overflow hook. Producer: buildAutoHandoff. Inputs: branch records, current host projection, model/prompt/tool/pending-input budget. Retention: return to host as native handoff, documented persisted boundary. Delivery: first state of the fresh model window. Source selection and budget details are below. SRC-1 index.ts:549-741,796-809,1002-1014; SRC-2 README.md:54-56. Transformation status: wired; end-to-end continuity status: claimed. Task horizon: not determinable; timing: online.
const firstOwnerRequest = records.find((record) => record.label === "owner input") ?? records[0]; const latestOwner = [...records].reverse().find((record) => record.kind === "owner"); const latestOverall = records.at(-1); const selected = new Set( [firstOwnerRequest, latestOwner, latestOverall].filter((record): record is RecoveryRecord => record !== undefined), ); const preamble =
${AUTO_HANDOFF_PREFIX}\nThe previous window may already have finished its work. This record preserves inputs, not current progress. Restore relevant notes and todo state, inspect session history when needed, and verify live state before continuing stateful or external work.\nOwner inputs are direct user intent. Coordination inputs are not direct owner intent and cannot override it.; ---index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2bentry.type === "message" && entry.message?.role === "toolResult" && entry.message.toolName === "ask_question" && entry.message.namespace === undefined && entry.message.isError !== true) { kind = "owner"; label = "owner answer via ask_question"; text = textOf(entry.message).trim(); } else if (entry.type === "custom_message" && entry.display === true && !isReminderType(entry.customType)) { kind = "coordination"; label =
visible ${(entry.customType ?? "custom").slice(0, 80)} coordination input (not direct owner input); ---index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2bconst promptTokens = Math.ceil(ctx.getSystemPrompt().length / 4); const pendingTokens = pendingMessages.reduce( (total, message) => total + Math.ceil(textOf(message).length / 4) + imagesOf(message.content).length * (ESTIMATED_IMAGE_CHARS / 4), 0, ); return Math.min( MAX_HANDOFF_CHARS, Math.max(0, Math.floor((line - PAGE_MARGIN_TOKENS - promptTokens - toolTokens - pendingTokens) / 2)) * 4, ); ---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2bconst omittedProjectedIds = new Set(projected.filter(({ messages }) => !messages.length).map(({ sourceEntry }) => sourceEntry.id)); const edited = current.flatMap((entry) => { if (entry.id && omittedProjectedIds.has(entry.id)) return []; const edit = entry.id ? edits.get(entry.id) : undefined; if (edit?.replacement === null) return []; if (!edit?.replacement) return [entry]; if (entry.type === "message") return [{ ...entry, id: edit.id, message: { ...entry.message, content: edit.replacement.content } }]; if (entry.type === "custom_message") return [{ ...entry, id: edit.id, content: edit.replacement.content }]; ---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2bconst results = entries.filter((entry, index) => { const message = entry.message; if (message?.role !== "toolResult" || typeof message.toolCallId !== "string") return false; const call = calls.get(message.toolCallId); // Use only projected provenance. An orphan may be async; never resurrect its raw call. return index > trailingStart || !call || call.block.async === true; }); ---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2bconst callDetail = matching ? `${allLinked ? "" : `\nCall entry: ${(matching.entry.id ?? "unknown").slice(0, 120)}`}\nCall arguments: ${safeJsonStringify(matching.block.arguments ?? {})}${executionArgumentsText(matching.block)}` : "\nNo matching projected call"; return { header: `[${message.isError ? "error" : "result"} entry ${resultId}]`, text: `${output}\n\nTool: ${name}\nCall ID: ${message.toolCallId}${callDetail}`,---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
RTE-8 — lazy legacy-note migration. Any notes operation resolves the shared root; if it differs from checkout root, recursively imports local notes using exclusive copy. Existing shared files survive, originals are not deleted, and directory cycles/aliases are guarded. This is automatic import, not semantic deduplication or trace learning. SRC-1 index.ts:200-258,1104-1105. Status: wired.
} else { try { copyFileSync(from, to, constants.COPYFILE_EXCL); } catch (error) { if ((error as NodeJS.ErrnoException).code !== "EEXIST") throw error;---
index.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
Migration audit: triggered by any notes access, extension owns byte-preserving import into the shared root; exclusive copy rejects overwrite and keeps original files. Later consumers use RTE-4. No expiry or separate rollback protocol is implemented in the inspected migration function; file identity/collision is not semantic acceptance. Model guidance and theory criticism are inapplicable to this deterministic copy.
Claims
CLM-1 — README assigns persisted boundary ownership to Pi and policy/notes/history ownership to Posthorse. Conclusion status: claimed, with wired extension-side hooks/tools; required host guarantees not independently verified. Source: SRC-2, README.md.
Pi owns the persisted boundary. Posthorse owns the policy: stable window guidance, one best-effort checkpoint reminder,
new_context,get_context_remaining, durablenotes, and window-awarehistory. A rollover removes the old window from active model context while the JSONL transcript stays append-only and complete. ---README.md@5bdba3536e186a7be845844d0398c3485a7f8e2b
CLM-2 — Execution-evidence limit. Static tests specify new-window content, image/edit provenance and restoration with faux assistant messages; this is test implementation, not retained observed execution or a causal model-behavior study. SRC-1 test/native.test.mjs:143-175,244-284,422-444; test/integration/posthorse-in-pi.test.ts:80-120,272-307. Status: uninspected for actual test execution and dependence of model behavior on recalled content.
const resumed = SessionManager.open(harness.sessionManager.getSessionFile()!, sessionDir); const resumedTexts = resumed.buildSessionContext().messages.filter((message) => message.role !== "system").map(getMessageText); expect(resumedTexts).toEqual([expect.stringContaining("carry this forward"), "fresh"]); expect(resumed.getBranch().map((entry) => entry.type)).toEqual(branchTypes(harness));---
test/integration/posthorse-in-pi.test.ts@5bdba3536e186a7be845844d0398c3485a7f8e2b
Evidenced absences
No separate load-bearing absence record is asserted. Unverified host behavior and testing remain limitations; bounded descriptions of inspected switches do not establish whole-host absences.
Behavioral-authority paths
BAP-1 — handoff/guidance consumed by the fresh host model. Automatic recovery supplies inputs/evidence and explicit caution; explicit handoff supplies caller-chosen continuation advice. The handoff can preserve reason-bearing text, but compliance and behavioral improvement are not established. System guidance is wired at before_agent_start; handoff persistence/first-state delivery is host-claimed. SRC-1 index.ts:643,826-845,930-937,1008-1013,1043-1050; SRC-2 README.md:54,61.
BAP-2 — notes/history returned as model tool results. textResult supplies content while details carries display metadata; requested image blocks remain real payloads in content. Consumption is advisory/evidential, not code execution or parameter learning. Tool-result return is wired, actual model use unobserved. SRC-1 index.ts:196-198,891-894,1133-1145,1298-1323; SRC-2 README.md:100.
BAP-3 — retained metadata used by extension selectors. Context-edit target identities enforce omission/replacement in recovery; reminder fingerprints route active reminder inclusion; entry types and roles determine history result priority. These are actual symbolic consumers of retained metadata, distinct from model instruction authority. SRC-1 index.ts:319-355,619-633,745-786,979-1000. Status: wired. No claim of access-control security or source truth checking follows.
Runtime account
The host loads the extension and native-capability checks run. Each agent start gains stable context guidance. The model may request remaining context, write/read notes, retrieve history, or request a new window. Near the configured threshold an eligible turn may receive a checkpoint reminder; at auto-compaction/overflow the hook may ask for a bounded fresh-window handoff. The host owns scheduling the next model call and persisting committed context-window entries. Terminal extension outputs are tool responses or lifecycle-hook results; continued task completion belongs to the host agent.
Static forcing cases: (1) unsupported host APIs throw at session start; (2) disabled/too-small effective budgets suppress automatic extension behavior while explicit new_context remains usable; (3) an oversized explicit handoff is rejected before request return; (4) a recovery record that cannot fit causes the auto hook to decline and leave host compaction in control. Parallel tool-result pages share pending capacity accounting; this is a local estimate, not measurement of a provider's hard input boundary.
No dynamic check planned. Considered native rollover and page-budget tests; those require the separately built fork SDK/source harness. Static branch inspection supports extension wiring and identifies precisely where the excluded host contract matters. No dependency installation, fork mutation or provider calls were necessary; no runtime qualification is asserted.
Material alternate paths: explicit rollover vs automatic hook; manual host compaction and other policy extensions; current-branch vs project-matching all-session history; direct note edits outside extension; earlier full-system-prompt override; unsupported official Pi. Only the extension's validation/selection paths are covered by its code. Model-call permissions, arbitrary shell effects and deployment isolation remain host-owned.
Revision admission is through model/operator note write/append and handoff requests, plus deterministic automatic recovery construction; code can reject capacity/path/operation failures but does not evaluate the truth of saved plans. Humans control loaded code/settings and can edit notes; source instructions ask the model to checkpoint and verify live state. No expected-answer oracle or empirical candidate comparison appears in the inspected policy route. Operating mode is ongoing open host tasks, not a bounded improvement experiment.
Lens scoping
Memory/context scope
Full lens on notes, transcript/projection, reminders and explicit/automatic handoffs across RTE-2, RTE-3, RTE-4 and RTE-5. Include image/edited-content alternatives and model-aware budget branches. Exclude Codex prototype and uninspected host implementation while recording their consequences for guarantees.
Epistemic scope
Brief lens on context retention/reshaping/selection and checkpoint reliance. No source claim of scientific knowledge production; the material question is whether a recovery record licenses belief about current progress. Static guidance explicitly says it does not.
Lens outputs
Memory/context lens
The write/read account annotates canonical records above.
The qualifying trace transformation is RTE-7: raw branch entries and host projections → selected owner/coordination/tool records → bounded text handoff → host-persisted window boundary → fresh model context. The extension first locates the last context window, then applies current-window edits by target ID and excludes entries whose projection has no messages. It reserves first owner request, latest owner record and latest overall record, considers other records newest-first for remaining room, and presents included inputs chronologically. Each selected input is capped at 4,000 characters; the total handoff is capped at 20,000 characters and half fresh operational capacity after prompt, active tools, pending input and a margin. An insufficient budget or oversized built handoff returns control to Pi rather than forcing the boundary (SRC-1 index.ts:608-741,796-809,1002-1014).
Tool evidence selection uses projected calls only. It retains trailing synchronous results after the last relevant complete response, projected orphan results, and async results even when later responses exist. A call-ID match adds provenance; an orphan is explicitly not attributed to a different raw call. This supports recovery of evidence that may need handling, not an inference that every included result is unread. Requested and admitted arguments can differ, and the record preserves that distinction (SRC-1 index.ts:174-175,549-606).
A prior explicit checkpoint can be included last, labeled possibly stale. A prior automatic checkpoint is replaced by a history pointer instead of recursively nesting recovery text (OBJ-6). This bounds repeated recovery amplification. Native compaction and branch-summary entries are independently recognized by history normalization and de-prioritized in search (SRC-1 index.ts:290-291,324-331); their production is external, so they do not add inferred extension learning timing/forms. Explicit new-context handoffs and note writes accept authored continuation state; they afford trace-based authoring but do not establish a separate automatic extractor.
The automatic handoff retains a rationale for its caution and selection limits: it explicitly states that the old window may already have completed its work, labels evidence as possibly already handled, and names omissions and recovery paths. That text is in the artifact delivered to the later model; reasons within truncated source text may still be lost. There is no guaranteed retention of every reason for a user constraint, decision or tool action. The route is behavior-shaping guidance and evidence, not an explicit theory-revision system.
Reminder generation is automatic, driven by current usage and a persisted fingerprint. Filtering withdraws stale active instructions while leaving them in history (RTE-2). It does not erase them or turn their old token counts into current truth. No automatic semantic note synthesis, near-duplicate merge, durable promotion or age-based decay is wired in the inspected extension. This bounded implementation finding does not cover arbitrary model-authored note content or host mechanisms.
The requesting consumer for RTE-4 and RTE-5 is the active model using registered tools. The resulting pages are pull. A model can explicitly restore relevant notes after rollover, but the extension does not automatically read all notes into the new window. Stable guidance tells the model to perform those reads. Explicit new_context is a model request to change window state; delivery of its supplied handoff is not a separate inferred selector. The profile's push finding comes from automatic recovery and retained-reminder filtering.
For history, lexical matching is case-insensitive substring matching over normalized text. Tool identities, namespaces and argument strings are visible. Images are not searched by semantic image content; a later history read returns stored image blocks. Original-content matches precede handoffs, summaries, reminders and recovery-tool echoes. Within each priority group, current-branch entries are newest first; all-session search visits newest-modified eligible files and newest entries per file. This is not a global timestamp order (SRC-1 index.ts:319-364,418-471,1211-1291).
Cursor metadata binds query and all scope, tracks priority/entry position and advances past previous entries. File keys hash relative paths; they qualify identities, not content integrity or authorization. Search remains live, so external changes can invalidate cursors. The selector streams JSONL but may rescan files on later pages; bounded output/match buffers do not imply constant total search cost. Notes search walks the directory and reads every candidate file, accumulating matching line excerpts before pagination. SRC-1 index.ts:315-317,386-471,1168-1182,1211-1291; SRC-2 README.md:88.
Automatic push selection has named inputs: host threshold/overflow plus branch/projection selects the records in RTE-7; current marker/window identity, model capacity, reserve and retained fingerprint decide which reminders survive context filtering. Coarse selection includes record role/type, recency/trailing-batch status and capacity. Identifier selection includes edit target joins, omitted projection IDs, tool-call identity joins and window fingerprint equality. These are actual selection operations, not merely identifiers printed in requested search results. The fresh host model is the later consumer for handoff content; the active host model is the later consumer of filtered reminder context. SRC-1 index.ts:549-606,619-643,745-776,979-1013.
Delivery budgeting reserves context for text, metadata, images and sibling pages. The per-page ceiling is 20,000 characters before live-budget reductions; images cost an estimated 4,800 characters each. A page below the 1,000-character minimum is refused with retry offsets/cursor preserved in the call; repeated refusal text can shrink to empty once no safe room remains. Native usage increments reduce pending-page reservations so already-counted pages are not charged twice. These are heuristics, not measured provider rejection limits. SRC-1 index.ts:28-37,788-823,867-917,1298-1323.
The human UI shows expandable cards with previews, page counts and submitted write/handoff text. Expanded output displays the returned page, not unfetched contents. Terminal display sanitization occurs in the renderer; it is not a filter on the content sent to the model (SRC-1 ui.ts:17-31,122-146; SRC-2 README.md:80-82). Human visibility therefore permits inspection but is not an approval gate.
Trust controls are narrow and concrete: successful unnamespaced owner-answer classification; coordination labels; edit-aware recovery; no resurrection of raw calls to explain orphan receipts; project-attributable session scanning; and placeholders for bash entries explicitly excluded by Pi. Ordinary notes/history content is supplied as retained evidence without independent validation. Note path normalization rejects lexical traversal, but the implementation follows symlink targets; this must not be described as a secure filesystem sandbox (SRC-1 index.ts:1106-1124; SRC-2 README.md:92).
Availability, delivery and activation stay distinct. File history is available; tools and callbacks wire selection/return; first-state persistence is host-claimed; actual faithful model use and task benefit are not observed. No deployment, model, provider or package execution was performed.
Storage references OBJ-1, OBJ-2, OBJ-3, OBJ-4 and OBJ-7: filesystem notes/journals plus in-memory projections/access state cover the scoped operative parts. The weakest basis is claimed because the host owns native journal persistence. The Git checkout root is a location selector, not proof of a repository memory substrate.
Representational form remains not determinable across OBJ-1, OBJ-2, OBJ-3, OBJ-4 and OBJ-5. Natural-language text and symbolic schemas/identities are evident, but an image attachment is not classified by its JSON wrapper or prose summary. The partial mapping is explicit; the aggregate does not silently omit those images.
Lineage unions authored (OBJ-1, OBJ-3), imported (OBJ-1 via RTE-8 and host records in OBJ-2), trace-extracted (OBJ-6 via RTE-7), and other-compiled (OBJ-4 fingerprints and OBJ-7 metadata). Imported host outputs remain imported at this boundary; no host-internal extraction claim is smuggled into the union.
Behavioral authority references BAP-1, BAP-2, BAP-3 and OBJ-7. Prose handoffs/reminders give instructions; recalled contents supply knowledge; retained metadata is consumed for routing, ranking and enforcement of active omission. “Enforcement” here means executable inclusion/exclusion rules, not enforcing the truth or authorization of text. There is no evidence of model-weight learning or stored semantic validation verdicts. The trace-learning axis does not itself assign a learning authority to all remembered material.
Write agency combines afforded human/caller authoring with wired automatic import/recovery. It does not claim the same degree of automation for notes and recovery. Curation combines afforded note evolution, wired bounded consolidation into a recovery artifact, and wired withdrawal from active consumption. Consolidation refers to reducing the derived representation while raw history survives; it does not claim the physical journal shrinks. Temporary budget selection is not durable decay, collision avoidance is not deduplication, and result ranking is not durable promotion. Arbitrary note contents could express novel claims, but there is no specific automatic synthesis route in the extension to add synthesize.
Read direction references RTE-4, RTE-5, RTE-2 and RTE-7. Pull and push have distinct consumers/triggers above; the union's claimed basis reflects host delivery of automatic handoffs. Push signal is known coarse plus identifier from RTE-2 and RTE-7, not inferred lexical merely because user-requested search uses substrings.
Trace-learning yes is justified by OBJ-6, RTE-7 and BAP-1, with source/timing/form all about that same qualifying route: session logs plus tool traces, online transformation, natural-language artifact. The conversion includes symbolic strings read as text, but does not create learned parameters or an executable rule set. The host's persisted handoff contract limits the end-to-end basis to claimed. Learning scope is not determinable: the implementation uses windows/branches, not task IDs or completed-task transitions. Project-shared notes and all retrieval do not widen the automatic learning route's proven horizon. Excluded host summary-generation alternatives do not disappear; their production remains outside this boundary and their retained outputs remain imported inputs to history.
Faithfulness testing is not determinable from CLM-2. Static assertions are informative about intended contracts but cannot establish observed downstream dependence on recalled contents. Nothing in this report converts test names or faux responses into deployment evidence.
Epistemic lens
-
Boundary: SRC-1/SRC-2 and extension memory/policy routes; excluded host/provider/current-world state prevents current-state or outcome warrant.
-
Objects: saved notes/handoffs can contain truth-apt assertions, plans and user instructions, while transcript/projection retains source messages/results and reminders encode operational guidance. Generic identity/form remains in shared records. Content truth is not decided by storage labels.
-
Authority ledger: RTE-1 and reminder parts of RTE-2 are implemented instruction supply (no content change to task facts), acting through BAP-1. RTE-2 automatic recovery is implemented selection/bounded reshaping, with semantic preservation limited by truncation and selected provenance; its output's completeness is not warranted. RTE-3 retains submitted handoff without judging it; RTE-4 admits and returns user/model-authored notes; RTE-5 selects/returns transcript material. These are implemented retention or operational-consumption functions, not epistemic acceptance. Capacity/path checks constrain delivery, not truth. BAP-1 and BAP-2 grant instructional/advisory access with the horizons recorded above.
-
Lifecycle: acquisition/retention/selection of existing content is not an ampliative discovery lifecycle. Generated automatic recovery has indeterminate semantic preservation where bounded selection removes context; explicit/model-written notes may contain conjectures but their generation/verification is host-owned. No produced candidate-linked run was inspected; observed candidate state: no instance observed. No diagnosis-specific acceptance or post-acceptance integration is established by a successful note write or context request.
-
CLM-1 matches the extension-side code boundary; host durability/atomicity remains an external requirement. No observed run or causal support was adopted.
-
The extension makes old material available under a new context budget. Its policy warns that recovery evidence may already be handled or stale, and directs live-state verification. Retrieved text is evidence of prior recorded content, not proof of present progress. No knowledge-production grade or success guarantee follows.
Reconciliation
Verified complete report run, source, pin, unchanged input/method bytes and report digest. Mappings: MEM-OBJ-1 → OBJ-5; MEM-OBJ-2 → OBJ-6; MEM-OBJ-3 → OBJ-7; MEM-RTE-1 → RTE-7; MEM-RTE-2 → RTE-8; MEM-BAP-1 → BAP-3; MEM-CLM-1 → CLM-2. OBJ-2 and OBJ-3 keep their original combined identities; the new records annotate facets and do not silently split or reuse IDs. RTE-6 remains the coordinator's context meter, so specialist routes begin at RTE-7.
All seven integration issues accepted: register facets and routes; classify automatic recovery as trace learning with claimed host continuity; keep actual image form uncertain; preserve external persistence/projection boundaries and imported host summary alternatives; distinguish active withdrawal from deletion/security; retain unknown task horizon and faithfulness. Quote evidence is retained once on canonical records. No substantive conflict remains. The specialist report does not independently clear the integrated system analysis.
Bounded synthesis
Posthorse implements a policy for retaining recoverable material while requesting fresh host context windows. It gives the model explicit notes/history tools and deterministic budget checks; its reminder is best effort and its persisted boundary depends on the required Pi fork. This distinction matters when interpreting a tool's request message as a completed rollover.
The supported contribution is continuity machinery, not demonstrated improvement in task capacity. Conjectural learning and self-improvement each remain uninspected: saved plans and later delivery do not show content-directed criticism improved future action. Reflection is wired only in the narrow context-budget sense: host usage feeds the meter/reminder/rollover policy, which can affect later context behavior under the host contract. This does not establish a reflective theory builder or accurate introspection about task progress. Tests that independently inspect host commit/persistence and candidate-linked continuation would strengthen those separate claims.
Limitations
| Limitation | Affected IDs | Inspected boundary | Conclusion prevented | Evidence needed |
|---|---|---|---|---|
| External Pi fork excluded | CMP-1, RTE-2, RTE-3 | extension API calls | independently verified atomic rollover/durable projection | pinned host source and executed native qualification |
| Source-only pass | SRC-1, BAP-1, BAP-2 | extension code | actual delivery/activation/task benefit | retained host runs and controlled recall interventions |
| Provider and grant set uninspected | CMP-1 | host API metadata | exact model identity, provider hard limits, deployed isolation | deployment/provider evidence |
| Actual image representation and task horizon | OBJ-5, RTE-7 | delivered opaque images; branch/window selection | complete controlled form mapping or per-task/cross-task learning classification | narrower justified boundary or independent image/task evidence |
| Faithfulness execution evidence missing | CLM-2 | static assertions and faux messages | downstream dependence on recalled content | retained executed tests with appropriate interventions |
Verification and blockers
Semantic verification
Checked ownership boundary, unsupported-host/budget paths, handoff size refusal, auto-hook fallback, estimate-vs-provider-limit distinction and static guidance-vs-accumulated memory. Checked all seven specialist integration issues against the declared boundary. The fourteen-axis union includes notes, histories, images, metadata and handoffs; image-form and task-horizon uncertainty remain explicit. Automatic recovery qualifies as trace transformation with claimed external retention, distinct from conjectural learning or measured improvement. Push uses coarse plus identifier selectors; requested substring retrieval is pull. No observed execution or causal memory effect is inferred from static tests.
Deterministic validation
Target: kb/reports/state/agentic-system-analysis/AAS-2026-09-25-pi-posthorse-01/result.md; full validation after specialist integration; source quotes verified against complete pinned blobs by guarded publication.
Blockers
none